{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Creating superposition states associated with discretized probability distributions\n",
    "\n",
    "#### Prerequisites\n",
    "Here are a few things you should be up to speed on before we start:\n",
    " - [Python fundamentals](https://qiskit.org/textbook/ch-prerequisites/python-and-jupyter-notebooks.html)\n",
    " - [Programming quantum computers using Qiskit](https://qiskit.org/textbook/ch-prerequisites/qiskit.html)\n",
    " - [Single qubit gates](https://qiskit.org/textbook/ch-states/single-qubit-gates.html)\n",
    "\n",
    "Additiona resources can be found [here](https://github.com/QForestCommunity/launchpad/blob/master/README.md).\n",
    "\n",
    "#### Dependencies\n",
    "\n",
    "We also need a couple of Python packages to build our distribution encoder:\n",
    "\n",
    " - [Qiskit](https://qiskit.org/)\n",
    " - [Numpy](https://numpy.org/)\n",
    " - [SciPy](https://www.scipy.org/)\n",
    " - [Matplotlib](https://matplotlib.org/)\n",
    " \n",
    "#### Contributors\n",
    "\n",
    "[Sashwat Anagolum](https://github.com/SashwatAnagolum)\n",
    "\n",
    "#### Qiskit Package Versions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'qiskit-terra': '0.14.1',\n",
       " 'qiskit-aer': '0.5.1',\n",
       " 'qiskit-ignis': '0.3.0',\n",
       " 'qiskit-ibmq-provider': '0.7.0',\n",
       " 'qiskit-aqua': '0.7.0',\n",
       " 'qiskit': '0.19.1'}"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import qiskit\n",
    "qiskit.__qiskit_version__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Introduction\n",
    "\n",
    "Given a probability distribution $p$, we want to create a quantum state $|\\psi\\rangle$ such that\n",
    "\n",
    "$$|\\psi\\rangle = \\sum_{i} \\sqrt{p_i} |i\\rangle$$\n",
    "where $|i\\rangle$ represents one of an orthonormal set of states.\n",
    "\n",
    "While we don't known when (for what kinds of distributions) we can do this, we do know that if you can efficiently integrate over a distribution classically, then we can efficiently construct a quantum state associated with a discretized version of that distribution.\n",
    "\n",
    "It may seem kind of trivial - we can integrate over the distribution classicaly, so why not just create the mixed state shown here?\n",
    "$$\\sum_i p_i |i\\rangle \\langle i |$$\n",
    "\n",
    "If all we needed to do was sample from the distribution, we could use this state - but then if we were efficiently integrating the distribution classicaly, say using Monte Carlo methods, we might as well sample from the classical distribution as well.\n",
    "\n",
    "The reason we avoid generating the distribution as a mixed quantum state is that we often need to perfom further, uniquely quantum, processing on it after creation - in this case, we cannot use the mixed state apporach.\n",
    "\n",
    "#### Encoding the distribution\n",
    "\n",
    "If we wanted to create a $N$ region discretization, we would need $n = log N$ qubits to represent the distribution. Let's look at a super simple case to start off: $N = 2$, so $n = 1$.\n",
    "\n",
    "We have probabilities $p_{0}^{(1)}$ and $p_1^{(1)}$, of a random variable following the distribution lying in region $0$ and region $1$, respectively, with $p^{(i)}_{j}$ representing the probability of measuring a random variable in region $j$ if it follows the discretized distribution over $i$ qubits.\n",
    "\n",
    "Since we only use one qubit, all we need to do is integrate over region $0$ to find the probability of a variable lying within it. Let's take a quick look at the Bloch sphere:\n",
    "\n",
    "![Bloch Sphere](./img/load_probability_distributions/bloch.png)\n",
    "\n",
    "If a qubit is rotated about the y-axis by angle $\\theta$, then the probability of measuring it as zero is given by $\\cos (\\frac{\\theta}{2})^2$ - so we can figure out how much to rotate a qubit by if we're using it to encode a distribution:\n",
    "\n",
    "$$ \\theta = 2 * \\cos^{-1} \\left ( \\sqrt{p_{0}^{(1)}}\\right )$$\n",
    "\n",
    "$$p_{0}^{(1)} = \\int_{x^{(1)}_{0}}^{x_{1}^{(1)}}p(x) dx$$\n",
    "\n",
    "Where $x^{(1)}_{0}$ and $x_{1}^{(1)}$ are the first and second region boundaries when 1 qubit is used. This leaves us with\n",
    "\n",
    "$$|\\psi \\rangle = \\sqrt{p_{0}^{(1)}} |0\\rangle + \\sqrt{p_{1}^{(1)}} |1\\rangle$$\n",
    "    \n",
    "Awesome!\n",
    "\n",
    "Now that we know how to do it for distributions with two regions, let's see if we can expand it to include more regions - i.e., can we convert a quantum state encoding a $N$ region discretization into one encoding a discretization with $2N$ regions?\n",
    "\n",
    "To get started, let's avoid all the complicated integration stuff we'll need to do later by defining a function $f(i, n)$ such that\n",
    "\n",
    "$$f(i, n) = \\frac{\\int_{x_{k}^{(n + 1)}}^{x_{k + 1}^{(n + 1)}} p(x) dx}{\\int^{x_{i + 1}^{(n)}}_{x_{i}^{(n)}} p(x) dx}$$\n",
    "\n",
    "Where $k = 2 * \\left ( \\frac{i}{2} - \\frac{i \\% 2}{2} \\right )$. The equation above probably looks a little hopeless, but all it does it computes the conditional probability of a value lying in the left subregion of region $i$ (when we have $N$ regions), given that it lies in region $i$. \n",
    "\n",
    "Why do we need this?\n",
    "\n",
    "We're assuming that dividing the distribution into $N$ regions is just an intermediary step in the process of dividing it into the desired $2^{m}$ regions - so $x_{k}^{(n + 1)}$ refers to the same boundary that $x_{i}^{(n)}$ does.\n",
    "\n",
    "Now that we've defined $f(i, n)$, all we need to do to figure out how much to rotate the $(n + 1)^{th}$ qubit is compute\n",
    "\n",
    "$$\\theta_{i}^{(n + 1)} = 2 * \\cos^{-1} \\left ( \\sqrt{f(i, n)}\\right )$$\n",
    "\n",
    "Now all we need to do is rotate the $(n + 1)^{th}$ qubit by $\\theta_{i}^{(n + 1)}$ conditioned on the state $|i\\rangle$ represented using $n$ qubits:\n",
    "\n",
    "$$\\sqrt{p_{i}^{(n)}}|i\\rangle \\rightarrow \\sqrt{p^{(n + 1)}_{k}}|k\\rangle + \\sqrt{p^{(n + 1)}_{k + 1}}|k+1\\rangle$$\n",
    "\n",
    "Since we showed that constructing a state for $n = 1$ was possible, and given a $2^n$ region discretization, we could convert into a distribution with $2^{(n + 1)}$ regions, we just inductively proved that we can construct a superposition state corresponding to a $2^n, n \\in \\mathbb{N}$ region discretized distribution - pretty cool!\n",
    "\n",
    "Now that we've gotten the concepts down, let's move on to building our own quantum distribution encoder.\n",
    "\n",
    "#### Required modules"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from qiskit import QuantumRegister, ClassicalRegister\n",
    "from qiskit import Aer, execute, QuantumCircuit\n",
    "from qiskit.circuit.library.standard_gates import RYGate\n",
    "from numpy import pi, e, sqrt, arccos, log2\n",
    "from scipy.integrate import quad\n",
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's define a function representing our distribution, so that we can change super quickly whenever we want to. We'll start off with a super simple function, like $N(0, 2)$:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def distribution(x):\n",
    "    \"\"\"\n",
    "    Returns the value of a chosen probability distribution at the given value\n",
    "    of x. Mess around with this function to see how the encoder works!\n",
    "\n",
    "    The current distribution being used is N(0, 2).\n",
    "    \"\"\"\n",
    "    # Use these with normal distributions\n",
    "    mu = 0\n",
    "    sigma = 2\n",
    "    return (((e ** (-0.5 * ((x - mu) / sigma) ** 2)) / (sigma * sqrt(2 * pi))) / 0.99993665)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The 0.99993665 is a normalisation factor used to make sure the sum of probabilities over the regions we've chosen adds up to 1.\n",
    "\n",
    "Next, let's create everything else we need to compute $f(i, n)$:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def integrate(dist, lower, upper):\n",
    "    \"\"\"\n",
    "    Perform integration using numpy's quad method. We can use parametrized\n",
    "    distributions as well by using this syntax instead:\n",
    "    quad(integrand, lower, upper, args=(tupleOfArgsForIntegrand))\n",
    "    \"\"\"\n",
    "    return quad(dist, lower, upper)[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def computeRegionProbability(dist, regBounds, numRegions, j):\n",
    "    \"\"\"\n",
    "    Given a distribution dist, a list of adjacent regions regBounds, the\n",
    "    current level of discretization numRegions, a region number j, computes\n",
    "    the probability that the value random variable following dist lies in\n",
    "    region j given that it lies in the larger region made up of regions\n",
    "    [(j // 2) * 2, ((j + 2) // 2) * 2]\n",
    "    \"\"\"\n",
    "    totalRegions = len(regBounds) - 1\n",
    "    k = 2 * j\n",
    "\n",
    "    prob = integrate(dist, regBounds[(totalRegions // numRegions) * k],\n",
    "        regBounds[(totalRegions // numRegions) * (k + 1)]) / integrate(\n",
    "        dist, regBounds[(totalRegions // numRegions) * ((k // 2) * 2)],\n",
    "        regBounds[(totalRegions // numRegions) * (((k + 2) // 2) * 2)])\n",
    "\n",
    "    return prob"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$computeRegionProbability$ gives us the value of $f(i, n)$. We're finally ready to start writing the quantum part of our program - let's start by creating the registers and circuit we need:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def encodeDist(dist, regBounds):\n",
    "    numQubits = int(log2(len(regBounds) - 1))\n",
    "\n",
    "    a = QuantumRegister(2 * numQubits - 2)\n",
    "    c = ClassicalRegister(numQubits)\n",
    "    qc = QuantumCircuit(a, c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can create the looping construct we need to be able to iteratively divide the distribution into $2^m$ regions, starting from $n = 1$ ($2$ regions), and dividing until $n = log N$ ($N$ regions). We need to loop over the different regions in the current , and compute the value of $f(i, n)$ for each one:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "    for i in range(numQubits):\n",
    "        numRegions = int(2 ** (i + 1))\n",
    "\n",
    "        for j in range(numRegions // 2):\n",
    "            prob = computeRegionProbability(dist, regBounds, numRegions, j)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we need to apply the controlled rotations - but we also need to write in a special case for $n = 1$, because there are no qubits to condition the rotation on:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "            if not i:\n",
    "                qc.ry(2 * arccos(sqrt(prob)), a[2 * numQubits - 3])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Since we'll be using gates with an arbitrary number of control qubits, we use the ControlledGate:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "            else:\n",
    "                cGate = RYGate(2 * arccos(sqrt(prob))).control(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We know that we need to use the qubits indexed by $[0, 1, ..., i - 1]$ as control qubits, and the $n^{th}$ one as the target - but before we can apply the gate we need to perform a few bit flips to make sure that the $n^{th}$ qubit is rotated only when the control qubits are in the state $|i\\rangle$. We can figure out which qubits to flip using this function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def getFlipList(i, j, numQubits):\n",
    "    \"\"\"\n",
    "    Given the current level of desired level of discretization, the\n",
    "    current level of discretization i and a region number j,\n",
    "    returns the binary bit string associated with j in the form of\n",
    "    a list of bits to be flipped.\n",
    "    \"\"\"\n",
    "    binString = str(bin(j))[2:]\n",
    "    binString = (\"0\" * (numQubits - len(binString))) + binString\n",
    "    bitFlips = []\n",
    "\n",
    "    for k in range(numQubits - i, numQubits):\n",
    "        if binString[k] == '0':\n",
    "            bitFlips.append(3 * numQubits - 3 - k - i)\n",
    "\n",
    "    return bitFlips"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here the variable j represents the region number, which we convert to binary, and then flip qubits so that the resulting binary string is all ones. After finding out which qubits we need to flip, we can create a controlled gate and append it to the quantum circuit back in $encodeDist$:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "                for k in listOfFlips:\n",
    "                    qc.x(a[k])\n",
    "\n",
    "                qubitsUsed = [a[k] for k in\n",
    "                    range(2 * numQubits - 2 - i, 2 * numQubits - 2)]\n",
    "\n",
    "                qubitsUsed.append(a[2 * numQubits - 3 - i])\n",
    "                qc.append(cGate, qubitsUsed)\n",
    "\n",
    "                for k in listOfFlips:\n",
    "                    qc.x(a[k])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "All that's left is to return the quantum circuit:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "    return qc, a, c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here's the entire function, so that we can run it in the notebook:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def encodeDist(dist, regBounds):\n",
    "    \"\"\"\n",
    "    Discretize the distribution dist into multiple regions with boundaries\n",
    "    given by regBounds, and store the associated quantum superposition\n",
    "    state in a new quantum register reg. Please make sure the number of \n",
    "    regions is a power of 2, i.e. len(regBounds) = (2 ** n) + 1.\n",
    "\n",
    "    Additionally, the number of regions is limited to a maximum of\n",
    "    2^(n // 2 + 1), where n is the number of qubits available in the backend\n",
    "    being used - this is due to the requirement of (n - 2) ancilla qubits in\n",
    "    order to perform (n - 1) control operations with minimal possible depth.\n",
    "\n",
    "    Returns a new quantum circuit containing the instructions and registers\n",
    "    needed to create the superposition state, along with the size of the\n",
    "    quantum register.\n",
    "    \"\"\"    \n",
    "    numQubits = int(log2(len(regBounds) - 1))\n",
    "\n",
    "    a = QuantumRegister(2 * numQubits - 2)\n",
    "    c = ClassicalRegister(numQubits)\n",
    "    qc = QuantumCircuit(a, c)\n",
    "\n",
    "    for i in range(numQubits):\n",
    "        numRegions = int(2 ** (i + 1))\n",
    "\n",
    "        for j in range(numRegions // 2):\n",
    "            prob = computeRegionProbability(dist, regBounds, numRegions, j)\n",
    "\n",
    "            if not i:\n",
    "                qc.ry(2 * arccos(sqrt(prob)), a[2 * numQubits - 3])\n",
    "            else:\n",
    "                cGate = RYGate(2 * arccos(sqrt(prob))).control(i)\n",
    "                listOfFlips = getFlipList(i, j, numQubits)\n",
    "\n",
    "                for k in listOfFlips:\n",
    "                    qc.x(a[k])\n",
    "\n",
    "                qubitsUsed = [a[k] for k in\n",
    "                    range(2 * numQubits - 2 - i, 2 * numQubits - 2)]\n",
    "\n",
    "                qubitsUsed.append(a[2 * numQubits - 3 - i])\n",
    "                qc.append(cGate, qubitsUsed)\n",
    "\n",
    "                for k in listOfFlips:\n",
    "                    qc.x(a[k])\n",
    "\n",
    "    return qc, a, c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, we can call our function, and compare the results with those from a classical computer - we also need a helper function that pads bit strings for us, so that we can plot the classical results on the same axis as the quantum ones:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA7IAAAIICAYAAABTptJTAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nOzdeXhV1aH+8XedzCEDZABCAiRhJiMzToAiDq1ap1qtdWi9tbbW9trbXu3Va62tvdbrrS3XVn9WrVpta0trnWtVBhURTWQmYQ4kJEBIQhLInLN+f+TADRAICUnWOcn38zx5OFn77L3fA3+EN2vvtY21VgAAAAAABAqP6wAAAAAAAHQFRRYAAAAAEFAosgAAAACAgEKRBQAAAAAEFIosAAAAACCgUGQBAAAAAAEl2HWA7kpISLCpqamuYwAAAAAAekF+fv5+a21iR9s6LbLGmJGSnpc0XJJX0pPW2l8ZY+IkvSQpVVKRpGustVW+fX4o6RZJrZK+Y6192zc+TdKzkiIkvSnpu9Zaa4wJ851jmqQKSV+y1hadLFdqaqry8vI6iw8AAAAACEDGmJ0n2nYqlxa3SPo3a+0kSbMl3W6MmSzpbknvWWvHSXrP9718266VlCHpIkm/McYE+Y71uKRbJY3zfV3kG79FUpW1dqykRyX9vEufEAAAAAAwYHRaZK21Zdbaz3yvayUVSEqW9AVJz/ne9pyky32vvyDpT9baRmvtDklbJc00xiRJirHWrrDWWrXNwLbf5/CxFkmab4wxp/3pAAAAAAD9TpcWezLGpEqaImmlpGHW2jKprexKGup7W7Kk4na7lfjGkn2vjx0/ah9rbYukaknxHZz/VmNMnjEmr7y8vCvRAQAAAAD9xCkv9mSMiZL0V0n/aq2tOcmEaUcb7EnGT7bP0QPWPinpSUmaPn36cdsBAAAABKbm5maVlJSooaHBdRT0sfDwcKWkpCgkJOSU9zmlImuMCVFbiX3RWvs33/BeY0yStbbMd9nwPt94iaSR7XZPkVTqG0/pYLz9PiXGmGBJsZIqT/lTAAAAAAhoJSUlio6OVmpqqrjLcOCw1qqiokIlJSVKS0s75f06vbTYd6/q05IKrLW/aLfpVUk3+V7fJOmVduPXGmPCjDFpalvU6RPf5ce1xpjZvmPeeMw+h491taTFvvtoAQAAAAwADQ0Nio+Pp8QOMMYYxcfHd3km/lRmZM+SdIOkdcaY1b6x/5D0kKQ/G2NukbRL0hclyVq7wRjzZ0kb1bbi8e3W2lbfft/U/z1+5y3fl9RWlH9vjNmqtpnYa7v0KQAAAAAEPErswNSdf/dTWbX4Q2utsdZmW2tzfV9vWmsrrLXzrbXjfH9WttvnQWvtGGvtBGvtW+3G86y1mb5t3z4862qtbbDWftFaO9ZaO9Nau73LnwQAAAAA/Nwvf/lL1dXVuY6hpUuX6qOPPjry/RNPPKHnn3++R479s5/9rEeOczJdWrUYAAAAANB9/lpkb7vtNt144409cmyKLAAAAAD0kQcffFATJkzQ+eefr+uuu06PPPKIJGnevHnKy8uTJO3fv1+pqamSpKKiIp1zzjmaOnWqpk6deqQYLl26VPPmzdPVV1+tiRMn6vrrr5e1VgsXLlRpaanOPfdcnXvuuZKkqKioI+dftGiRbr75ZknSzTffrG9+85s699xzlZ6ermXLlulrX/uaJk2adOQ9x8rPz9fcuXM1bdo0XXjhhSorK5MkLVy4UJMnT1Z2drauvfZaFRUV6YknntCjjz6q3NxcffDBB7r//vuP+rx33nmn5syZo0mTJunTTz/VlVdeqXHjxunee+89cr7LL79c06ZNU0ZGhp588klJ0t133636+nrl5ubq+uuvlyS98MILmjlzpnJzc/WNb3xDra2tOl2n/PgdAAAAAOgLP35tgzaW1vToMSePiNGPLs044fb8/Hz96U9/0qpVq9TS0qKpU6dq2rRpJz3m0KFD9c477yg8PFxbtmzRddddd6Twrlq1Shs2bNCIESN01llnafny5frOd76jX/ziF1qyZIkSEhI6zVxVVaXFixfr1Vdf1aWXXqrly5frqaee0owZM7R69Wrl5uYeeW9zc7PuuOMOvfLKK0pMTNRLL72ke+65R88884weeugh7dixQ2FhYTpw4IAGDx6s2267TVFRUfr+978vSXrvvfeOOndoaKjef/99/epXv9IXvvAF5efnKy4uTmPGjNGdd96p+Ph4PfPMM4qLi1N9fb1mzJihq666Sg899JAee+wxrV7dtrxSQUGBXnrpJS1fvlwhISH61re+pRdffPG0Z38psgAAAAAGvA8++EBXXHGFIiMjJUmXXXZZp/s0Nzfr29/+tlavXq2goCBt3rz5yLaZM2cqJaXt6aO5ubkqKirS2Wef3aVMl156qYwxysrK0rBhw5SVlSVJysjIUFFR0VFFdtOmTVq/fr0WLFggSWptbVVSUpIkKTs7W9dff70uv/xyXX755ad07sOfPysrSxkZGUeOlZ6eruLiYsXHx2vhwoV6+eWXJUnFxcXasmWL4uPjjzrOe++9p/z8fM2YMUOSVF9fr6FDh3bp76EjFFkAAAAAfuVkM6e96USr5wYHB8vr9UrSUY+JefTRRzVs2DCtWbNGXq9X4eHhR7aFhYUdeR0UFKSWlpZOz3nsI2gOH8Pj8Rx1PI/Hc9zxrLXKyMjQihUrjjvHG2+8offff1+vvvqqfvKTn2jDhg0dZunKuZcuXap3331XK1asUGRkpObNm9fhI3Sstbrpppv0X//1X52esyu4RxYAAADAgDdnzhy9/PLLqq+vV21trV577bUj21JTU5Wfny+p7T7Ww6qrq5WUlCSPx6Pf//73p3TvZ3R0tGpra498P2zYMBUUFMjr9R6Z3eyOCRMmqLy8/EiRbW5u1oYNG+T1elVcXKxzzz1XDz/8sA4cOKCDBw8el6OrqqurNWTIEEVGRqqwsFAff/zxkW0hISFqbm6WJM2fP1+LFi3Svn37JEmVlZXauXNnt897GEUWAAAAwIA3depUfelLX1Jubq6uuuoqnXPOOUe2ff/739fjjz+uM888U/v37z8y/q1vfUvPPfecZs+erc2bN2vQoEGdnufWW2/VxRdffGSxp4ceekiXXHKJzjvvvCOX73ZHaGioFi1apLvuuks5OTnKzc3VRx99pNbWVn3lK19RVlaWpkyZojvvvFODBw/WpZdeqpdffvnIYk9dddFFF6mlpUXZ2dn6z//8T82ePfuoz3j4cubJkyfrpz/9qS644AJlZ2drwYIFRxahOh3G9yjXgDN9+nR7+EZqAAAAAIGtoKBAkyZNch3jiPvvv/+oxZDQuzr69zfG5Ftrp3f0fmZkAQAAAAABhcWeAAAAAOAY999/v+sIOAlmZAEAAAAAAYUZWQAA+tCnRZX69h8+08ghkZowPFoTk2I0aXi0JgyPVnR4iOt4AAAEBIosAAB96PU1pTpQ16zRcUavrinViyt3HdmWMiRCE4fHaFJStCYOj9HEpGilxg9SkKfj5xoCADBQUWQBAOhDm7Zs0v+L/YvmDRsse8svVXrIqmrFCwouWqLq+mZVlzTr4NYW1ctofvNtCgv26PbYj3Rm8CbFRoYoNqLtKywiSrrk0baDfvJbaXf+0SeKGCJd1LMPnwcAwF9QZAEA6CP7aho0+8Drmhv8D2nnSBlZJQ+OUHJEpdS4rm3likGSN1Jq8Uqal6PCshqlFf5NSdWr5K2yapS0T1KDJ0IP7F2pSUkx+tK+fI2s+FAhHiNzePI2arizzwkA/UlPP4bnzDPP1EcffeQkR1FRkT766CN9+ctfliTl5eXp+eef18KFC7t9zMOeffZZXXDBBRoxYsRpH+tUUGQBAOgjK7ZX6GzPetUn5ijy9mX/t2HeXW1fPh5JoZKuPjxwyW8lSeW1jdq0p1aFe2pUUFaryj01enZ5kZ5svVTSpQr2GI1JjNLEpLZ7bqesLdSsQXvkGTOvbz4gAKBT3SmxPaWoqEh/+MMfjhTZ6dOna/r0Dh/T2mXPPvusMjMz+6zIsmoxAAB95LNNRcr1bFX4xPO7tX9idJjOHpegfzknXf9zTY7e+M452vjAhXrnzjn63+um6Btz05UyJEJ5RVV6+B+bVPDnH8n+4UtSc0MPfxIA6J+ef/55ZWdnKycnRzfccMNx23/7299qxowZysnJ0VVXXaW6ujpJ0l/+8hdlZmYqJydHc+bMkSRt2LBBM2fOVG5urrKzs7VlyxZJUlRU1JHjPfzww8rKylJOTo7uvvvuk57jRMrLy3XVVVdpxowZmjFjhpYvXy5JWrZsmXJzc5Wbm6spU6aotrZWd999tz744APl5ubq0Ucf1dKlS3XJJZdIapvxvemmm3TBBRcoNTVVf/vb3/Tv//7vysrK0kUXXaTm5mZJ0gMPPKAZM2YoMzNTt956q6y1WrRokfLy8nT99dcrNzdX9fX1ys/P19y5czVt2jRdeOGFKisrO51/muMwIwsAQB8p3b5edZ4YxYyd32PHDA7yaNywaI0bFq1Lc/7vt+DVdc2675F1Cmr9h1T8sZQ+r8fOCQB94nefP34s43Jp5telpjrpxS8evz33y9KU66VDFdKfbzx621ffOOnpNmzYoAcffFDLly9XQkKCKisrj3vPlVdeqa9//euSpHvvvVdPP/207rjjDj3wwAN6++23lZycrAMHDkiSnnjiCX33u9/V9ddfr6amJrW2th51rLfeekt///vftXLlSkVGRh4534nOcSLf/e53deedd+rss8/Wrl27dOGFF6qgoECPPPKIfv3rX+uss87SwYMHFR4eroceekiPPPKIXn/9dUnS0qVLjzrWtm3btGTJEm3cuFFnnHGG/vrXv+rhhx/WFVdcoTfeeEOXX365vv3tb+u+++6TJN1www16/fXXdfXVV+uxxx7TI488ounTp6u5uVl33HGHXnnlFSUmJuqll17SPffco2eeeeak/wZdQZEFAKAPFFfW6Z3qFP3tksW6eWRar58vNjJEEePmqHnTwwraulie9Hm9fk4ACGSLFy/W1VdfrYSEBElSXFzcce9Zv3697r33Xh04cEAHDx7UhRdeKEk666yzdPPNN+uaa67RlVdeKUk644wz9OCDD6qkpERXXnmlxo0bd9Sx3n33XX31q19VZGTkUec70TlO5N1339XGjRuPfF9TU6Pa2lqdddZZ+t73vqfrr79eV155pVJSUjr9O7j44osVEhKirKwstba26qKLLpIkZWVlqaioSJK0ZMkSPfzww6qrq1NlZaUyMjJ06aWXHnWcTZs2af369VqwYIEkqbW1VUlJSZ2evysosgAA9IEV2yokSWeOGyp5+ubOnrMmpyq/YLyyC99R5AUP9Mk5AaDHnGwGNTTy5NsHxXc6A3ssa62MOfnjzm6++Wb9/e9/V05Ojp599tkjM5pPPPGEVq5cqTfeeEO5ublavXq1vvzlL2vWrFl64403dOGFF+qpp57Seeed1+n5TnSOE/F6vVqxYoUiIiKOGr/77rv1+c9/Xm+++aZmz56td999t9O/g7CwMEmSx+NRSEjIkXwej0ctLS1qaGjQt771LeXl5WnkyJG6//771dBw/O0r1lplZGRoxYoVnZ6zu7hHFgCAPrCpYI0+DP9XjTv0WZ+dc874RH3ozVZk5Ubp0P4+Oy8ABKL58+frz3/+syoq2n7x2NGlxbW1tUpKSlJzc7NefPHFI+Pbtm3TrFmz9MADDyghIUHFxcXavn270tPT9Z3vfEeXXXaZ1q5de9SxLrjgAj3zzDNH7oE9fL4TneNELrjgAj322GNHvl+9evWRTFlZWbrrrrs0ffp0FRYWKjo6WrW1tV38m/k/h0trQkKCDh48qEWLFh3Z1v7YEyZMUHl5+ZEi29zcrA0bNnT7vB2hyAIA0MustQopWqYU7ZOJSe6z88ZGhGjTiMv1tZinpEEJfXZeAAhEGRkZuueeezR37lzl5OToe9/73nHv+clPfqJZs2ZpwYIFmjhx4pHxH/zgB8rKylJmZqbmzJmjnJwcvfTSS8rMzFRubq4KCwt1441H37N70UUX6bLLLtP06dOVm5urRx555KTnOJGFCxcqLy9P2dnZmjx5sp544glJ0i9/+csjC1BFRETo4osvVnZ2toKDg5WTk6NHH320y39HgwcP1te//nVlZWXp8ssv14wZM45su/nmm3XbbbcpNzdXra2tWrRoke666y7l5OQoNze3x1drNtbaHj1gX5k+fbrNy8tzHQMAgE5t3XdQW//3cp0dtVtR/75R6uTStZ70xLJteuitQn38w/kaHhveZ+cFgK4qKCjQpEmTXMeAIx39+xtj8q21HT4fiBlZAAB62Yote3SmZ71s2rw+LbGSdO6EoZrt2aiDi26XAvSX1wAAHIsiCwBALyvd+JFiTL2iJl/Q5+cePyxKOZFVGlu8SCov7PPzAwDQGyiyAAD0Iq/X6pPdTVo5+HMy6XP7/PzGGAWPP1eS1LKl8xUrAQAIBBRZAAB60cayGuU3JGn3nP+WIo9/JmFfmJadra3eEapZ/08n5weAUxWo6/fg9HTn350iCwBAL/p0U7EmmF06Mz3eWYYz0hP0kbIVvWel1Hz88/4AwB+Eh4eroqKCMjvAWGtVUVGh8PCuLUgY3Et5AACApIMF/9TbYT+WqnOkwWc6yRARGqSKYWereP9GpdfsluLHOMkBACeTkpKikpISlZeXu46CPhYeHq6UlJQu7UORBQCglzS3epW47yM1BkUoLLnDpwf0mfgpl+i8V9O12DtM6U6TAEDHQkJClJaW5joGAgSXFgMA0EvWllRrtl2rA8NmS8GhTrOcO3GYJGlJQZnTHAAA9ASKLAAAvWTD+tVK9exV1OQFrqNoZFykvjZkta5dMlc6yGV7AIDARpEFAKCXNG1eLEkaNKnvnx/bkZFpEzXIHlLD5vdcRwEA4LRQZAEA6AUNza36dUWu/jj2f6T4sa7jSJImTjlHVTZK+9e87ToKAACnhSILAEAv+GxnlapawjV02qWSMa7jSJKmpydopclS9O73JR5vAQAIYBRZAAB6weZ1n+iO4L9r5nDXSf5PSJBHFUPPUmzLftl9Ba7jAADQbRRZAAB6QdjWN3Rn8F8UHRbiOspRYrMu0mMtX9DmA66TAADQfRRZAAB62MHGFo2r/VR7B02SIuNcxznKrNxsPdLyJf2zxL8KNgAAXUGRBQCgh322aadyzRa1pM1zHeU4idFhmp4cof3r3pZaGl3HAQCgWyiyAAD0sL1r31Gw8Wpo7sWuo3TohmE79OMD96h68weuowAA0C0UWQAAelhF6TbVeGIUljrbdZQOpU+7UM02SHtWveU6CgAA3UKRBQCgB1UdatLPq+bp+TP+KQWHuo7ToYy0ZK01ExSx633XUQAA6BaKLAAAPejj7RWyVpo9bpjrKCfk8RjtG3qmRjVuVkvNPtdxAADoMoosAAA9qPGT3+nVsPuUHe86ycnFZFwgSSr69E3HSQAA6DqKLAAAPSiu7H0lB1crNGqI6ygnlTVjrq5ufkB/a5rhOgoAAF1GkQUAoIfsPXBQOc1rtG/oWZIxruOcVExkuIJHz9TiTRWuowAA0GUUWQAAekhh/vuKNXUaNGmB6yin5LLRLbp2//9q7471rqMAANAlFFkAAHpI46Z35JVR8lT/fH7ssc4cm6Cbg/+p4pV/dx0FAIAuocgCANBDlh5I1OLYKxUU5ecrPfmMTp+oXWaEQncucx0FAIAu6bTIGmOeMcbsM8asbzf2kjFmte+ryBiz2jeeaoypb7ftiXb7TDPGrDPGbDXGLDSm7eYhY0yY73hbjTErjTGpPf8xAQDoXcWVdfpDTY52z7rPdZRTZoxRafwZGlu3Rg31da7jAABwyk5lRvZZSRe1H7DWfslam2utzZX0V0l/a7d52+Ft1trb2o0/LulWSeN8X4ePeYukKmvtWEmPSvp5tz4JAAAOrVq/Xok6oDPHBMZs7GGRkxco0jSq8NN3XUcBAOCUdVpkrbXvS6rsaJtvVvUaSX882TGMMUmSYqy1K6y1VtLzki73bf6CpOd8rxdJmn94thYAgEAx5LNfa2n49zQ2Psx1lC4ZP/Nildk4bd6+3XUUAABO2eneI3uOpL3W2i3txtKMMauMMcuMMef4xpIllbR7T4lv7PC2Ykmy1rZIqpbU4a+zjTG3GmPyjDF55eXlpxkdAICeYa3VqAMrtWNQrkxwqOs4XRIeNVj3pr6k/92XrbbfNQMA4P9Ot8hep6NnY8skjbLWTpH0PUl/MMbESOpohvXwT8uTbTt60NonrbXTrbXTExMTTyM2AAA9p2jrRo1WmRpHz3MdpVvmTRqm4so6bdtX4zoKAACnpNtF1hgTLOlKSS8dHrPWNlprK3yv8yVtkzRebTOwKe12T5FU6ntdImlku2PG6gSXMgMA4I/KVr0lSUqa8jnHSbpnwYhGfRj2Xe18/0XXUQAAOCWnMyN7vqRCa+2RS4aNMYnGmCDf63S1Leq03VpbJqnWGDPbd//rjZJe8e32qqSbfK+vlrTYcm0TACCAhO1cpr2KV9KYLNdRumV4yhjFehoUtH2J6ygAAJySU3n8zh8lrZA0wRhTYoy5xbfpWh2/yNMcSWuNMWvUtnDTbdbaw7Or35T0lKStapupfcs3/rSkeGPMVrVdjnz3aXweAAD6VKvX6p5D1+pvaT+S8QTo49k9Qdo9ZKYm1uWppr7JdRoAADoV3NkbrLXXnWD85g7G/qq2x/F09P48SZkdjDdI+mJnOQAA8EcFZTUqbBis27JzXUc5LWETztfwFYu17LNPNPess13HAQDgpAL0V8cAAPiH0hUv6ZqgJTojPc51lNMycvrnJUkH1v3DcRIAADpHkQUA4DSM3vKcbglbrGGxEa6jnJbg+FT9c8iX9Vr5UHm9LFUBAPBvFFkAALqpue6A0hsKtCfhTNdResTBc+7Ru4fGaH1ptesoAACcFEUWAIBuKsp7WyGmVeETz3cdpUfMHZegSZ5d+nT1GtdRAAA4KYosAADdVFfwjg7ZMI2fNt91lB4RH9qs10LvUcyGF1xHAQDgpCiyAAB0U2PVbq0PzdaQ2GjXUXpGWLT2xmRrwqFPVV7b6DoNAAAnRJEFAKAbGppb9ZXa7+i9rF+4jtKjgsedp0xTpBXrNruOAgDACVFkAQDohvydVWpq9eqM8cNdR+lRQ3MvlsdYla9923UUAABOiCILAEA3xLz9Hf085LeakRbYz489lkmeqjpPlIaUfajmVq/rOAAAdIgiCwBAV3lblbp/mRIGBSsqLNh1mp7lCdLqeb/TfzZ+Rfk7q1ynAQCgQxRZAAC66FBRnqLtQdWNnOs6Sq/InnWemoIitaRwn+soAAB0iCILAEAX7V31przWaFjOha6j9IqoEKOfxb+lpnV/dx0FAIAOUWQBAOiioB1LtUFpyp4wxnWU3uEJ0gXNS3X2wbdVXFnnOg0AAMehyAIA0EXLWjK0cvAlCg8Jch2l94w9T2d4NmpZQYnrJAAAHIciCwBAF1QeatJ9Bz6v+uwbXUfpVTGTFyjSNKpk7TLXUQAAOA5FFgCALli3+lOFq1Fnjo13HaVXmbQ58ipIsWUfqr6p1XUcAACOQpEFAKALJr//DT0e9piyUwa7jtK7wmNUPXy2wr31WrF9v+s0AAAchSILAMCpqtqpxMZilcXNVEhQ//8RGvG1V/Ww+ZoW8xgeAICf6f8/hQEA6CHVG/4pSQoZP99xkr4RHhqss8YmaGnBXllrXccBAOCIYNcBAAAIFAc3/lN1Nk6Tsma4jtJnflL7n1pyKExb9s3S+GHRruMAACCJGVkAAE6Nt1VD9q7QSpOjySNiXafpM4MHD9HcoLVaXLDXdRQAAI6gyAIAcAqspDuC7tOakV+Rx2Ncx+kzERMXKNlUqHDDZ66jAABwBEUWAIBTsKuqQe/VJCtt8nTXUfrWmHMlSXFlH6q6rtlxGAAA2lBkAQA4BZXv/EKzTIHOHNO/nx97nCGpaohJ1ZlmrT7YWu46DQAAkiiyAAB0rrFW2YWP6uKI9RqTGOU6TZ8LPedf9WHwLB7DAwDwG6xaDABAJ+yODxSkVh1MniNjBs79sYd5ZnxVVdtW6cNN5fJ67YC6RxgA4J+YkQUAoBMH1r+tOhum4RlzXUdx5uJR0vC6zVpTcsB1FAAAmJEFAKAznu1LtNI7UbPGJ7mO4sz8DXdpREi53i08X1NGDXEdBwAwwDEjCwDAydQfkG08qHXh0zQyLtJ1GmdCxs1XpmeH8gq2uY4CAABFFgCAk2kNi9Wc1t9oz7ivuI7i1pjz5JHVkL0rtK+mwXUaAMAAR5EFAOAkNpbWqKahVbPGD3cdxa0RU9QaGqNzPGu1dBOP4QEAuEWRBQDgRLytSvrT+fpi0FKdkT7Anh97rKBgecbM07zg9VpcsNd1GgDAAMdiTwAAnEjZaiUc3KzBMZdqaEy46zTOmfn36VlbpA8LKtTU4lVoML8PBwC4wU8gAABOoGXLe5KkoDHnOk7iJxLGaWpWlg42tiivqNJ1GgDAAEaRBQDgBOoK3tF6b6pyJ451HcVvzGlerjtCXtXiwn2uowAABjCKLAAAHWms1aB9+frAm6XZA/3+2HbCS5br9uC/6/3C3a6jAAAGMIosAAAdaarT4ogLtS1ujgZHhrpO4z/GnKdw26AhFWu0s+KQ6zQAgAGKIgsAQAfqwxJ0e/WNipt4juso/iXtHFkTpLOD1mkJlxcDAByhyAIA0IGCNR+rubVFZ4zhsuKjhMfKpMzQgtANWszzZAEAjlBkAQA41oFiTX3jc7o5+B3NSI1zncb/jJ2vmPAg5W/fq7qmFtdpAAADEEUWAIBjbV8iSaoadoaiwnjk+nHm/EDbr3hDh1o8Wr61wnUaAMAARJEFAOAYzZvf1R47RCPHT3EdxT8Zo5lpcRoU6uExPAAAJyiyAAC0522V3b5MH3qzdMbYBNdp/FboR7/QO2F3aWnhXllrXccBAAwwFFkAANorW63QpgNaoWxNHTXEdRr/FTFEI5p3KqJ2hwr31LpOAwAYYCiyAAC0lzhJ9w76kWpHzlV4SJDrNP5rzEvxIMYAACAASURBVHmSpHM867i8GADQ5yiyAAC0U9EUpBcqJihnXLrrKP4tLk0akqbPRRbwPFkAQJ+jyAIAcFjjQVW8/mONNHt5fuypGHOeprSu19pd5TpQ1+Q6DQBgAKHIAgBw2M7lGl/4a40PrVR2cqzrNP4v8ypVZP+LQm2Tlm0ud50GADCAUGQBADhs22I1KFRBo89QcBA/IjuVepaGXvaAFBaj/J1VrtMAAAaQTn9KG2OeMcbsM8asbzd2vzFmtzFmte/rc+22/dAYs9UYs8kYc2G78WnGmHW+bQuNMcY3HmaMeck3vtIYk9qzHxEAgFPTsuU9fdw6STPHJbmOEjCCWup0RfxObSytcR0FADCAnMqvm5+VdFEH449aa3N9X29KkjFmsqRrJWX49vmNMebwko+PS7pV0jjf1+Fj3iKpylo7VtKjkn7ezc8CAED3HShWcOUWfeDN5P7Yrli+UD+u/HeVlpXK6+V5sgCAvtFpkbXWvi+p8hSP9wVJf7LWNlprd0jaKmmmMSZJUoy1doVte2r685Iub7fPc77XiyTNPzxbCwBAnynfpCYTptWhUzVpeIzrNIFjzHnyyCq3ZY2Kq+pcpwEADBCncwPQt40xa32XHh9+YnyypOJ27ynxjSX7Xh87ftQ+1toWSdWSOvxVuDHmVmNMnjEmr7ycRSUAAD3Hjp2vBSHPa2h6rjwefp96ypKnqTU4UjM9hVxeDADoM90tso9LGiMpV1KZpP/xjXf0k9+eZPxk+xw/aO2T1trp1trpiYmJXUsMAMBJ7Kyo086aVp05jp8vXRIULDM8S5meIm0so8gCAPpGt4qstXavtbbVWuuV9FtJM32bSiSNbPfWFEmlvvGUDsaP2scYEywpVqd+KTMAAKevuUGDXrhYCzx5OpP7Y7vMMyJXGZ5dKiw94DoKAGCA6FaR9d3zetgVkg6vaPyqpGt9KxGnqW1Rp0+stWWSao0xs333v94o6ZV2+9zke321pMW++2gBAOgb+zYo8cAaDQn3KD1hkOs0gWfm1/VY6q+4tBgA0GeCO3uDMeaPkuZJSjDGlEj6kaR5xphctV0CXCTpG5Jkrd1gjPmzpI2SWiTdbq1t9R3qm2pbATlC0lu+L0l6WtLvjTFb1TYTe21PfDAAAE5Z2RpJkh2eLdYb7IaEcYpJ82h3YaEO1DVpcGSo60QAgH6u0yJrrb2ug+GnT/L+ByU92MF4nqTMDsYbJH2xsxwAAPSWlpLVOmQjlTR6gusoAeuc5g/1iWenNpbN0pljElzHAQD0c6ezajEAAP1CY8kqrfemKSNlsOsoAWvc1t/pa0H/4PJiAECfoMgCAAa8vSEpet+brazkWNdRAlZIcq6ygoq0sbTadRQAwABAkQUADHiPx92tv4RfpaTYcNdRAldSjmJ0SJW7t7pOAgAYACiyAICBzduq9aU1ykyOZaGn05GUI0mKqlyvphav4zAAgP6OIgsAGNBa3rxLCyu+oawR0a6jBLahk+U1wUq3Jdqyr9Z1GgBAP0eRBQAMaA27PlOVopSZzEJPpyUkXDtvytfC1itY8AkA0OsosgCAgcvbqvCKDdrgTVUmCz2dtlGjRis8JEgFZczIAgB6F0UWADBwVWxVcGuDtgWPVcqQCNdpAl7Q3rX6f5FPqKxku+soAIB+jiILABi4ytZKklqGZbPQU09obtDcxqUK3rtG1lrXaQAA/RhFFgAwYDXFjtLzrRcoblSm6yj9w/BMWRmlN29TaXWD6zQAgH6MIgsAGLA2BU3Ufc03a/LIONdR+ofQQWqITVemp4gFnwAAvYoiCwAYmKxV8aY8BalVWSz01GNCkqcow7ODIgsA6FUUWQDAwFS1Q5/74ErdEP6BRsVFuk7TbwSPmq76oBht3b3PdRQAQD8W7DoAAABOlK2RJDUlsNBTj5r9Tf1i2yyt213tOgkAoB9jRhYAMCC1lq5Rsw1SbGq26yj9zuQRMdpVWafahmbXUQAA/RQzsgCAAalu52faZVM0MSXBdZR+58qdP1V8cJUK95yhGakspAUA6HnMyAIABh5rFbJvndZ701joqRcMCWnRGZ6NLPgEAOg1FFkAwMBjrf6c8kO9HHSBUuMHuU7T74SNnKLRnn3aUbzbdRQAQD9FkQUADDwej14+mCHviKnyeFjoqaeZETmSpKbdqx0nAQD0VxRZAMCA07JjuWLKPuKy4t4yvK3IxlRtVEur13EYAEB/RJEFAAw4DUt/oXvM75SZHOM6Sv8UlajilM+ruDVO2/cfcp0GANAPUWQBAAOOZ+86rbcs9NSbDl3yhN7wzmbBJwBAr6DIAgAGloP7FNmwV5tNutISolyn6bfGJEYpNqhJm3ZXuo4CAOiHKLIAgIGlbK0kqS4+Q0Es9NRrQna+r1UhX1Xjrk9dRwEA9EMUWQDAgOItbVtJN2LUFMdJ+rmE8fLIKrx8nay1rtMAAPoZiiwAYEDZNu6rurDxIY0blew6Sv8WnaT60DilNW9VeW2j6zQAgH6GIgsAGFDW763XJjuKhZ56mzFqTMhSpqdIG8pY8AkA0LMosgCAgaO+SkkrfqKskN0akzjIdZp+L3z0VI0zJdpUUu46CgCgnwl2HQAAgD5Ttlaz9/1J0+IzFRzE73J7W3jmpfplXo12lR1wHQUA0M9QZAEAA4a3dI08ksJHstBTn0iepo0jrbbuPeg6CQCgn+HX0QCAAePQznyV2ASljxrtOsqAMTOuThEVG1TX1OI6CgCgH6HIAgAGjrI12uBNVSYLPfWZK3Y9qJ8FP6VNe2pdRwEA9CMUWQDAwNDSKDXWqkBpGjcsynWaASMkZYomml0q2F3hOgoAoB+hyAIABobgMN2a+KKWDb1BISz01GeiU6cpzLSoYsda11EAAP0IP8kBAAOCtVbrS6s1OSXOdZQBxYzIbXtRtsZtEABAv0KRBQAMCNWv36d/a3mK+2P7WtwYNXoiNaSmUK1e6zoNAKCfoMgCAAYEz5Z/aJTZpyyKbN/yeLRi5kL9pvFz2llxyHUaAEA/QZEFAPR/zfWKqtnGQk+OJGRdoFIlaGNZjesoAIB+giILAOj/9m6UR606EDtJYcFBrtMMOGMj63Rz8DsqLtriOgoAoJ+gyAIA+j1btlqSFJwyxXGSgSm8qVL3B/9Onp0fuY4CAOgngl0HAACgt1U2BWmrd6KSR493HWVgSpigJhOqqKoNrpMAAPoJiiwAoN/7JOZCfbMpUa+kDHYdZWAKCtaB6PFKq9qmioONio8Kc50IABDguLQYANC/eb1aV1KlYI/RhOHRrtMMWK3DspXpKVJBKQs+AQBOH0UWANC/7V2v2z85X1+M26bwEBZ6ciUmbbpiTJ127Sh0HQUA0A9QZAEA/ZotW61B9pCGJKW5jjKgDZp2jc4LeUGfHmBWHABw+rhHFgDQrx3a+ZmsjdDwtMmuowxsYdFKTR6ujVxaDADoARRZAEC/1lyyWpvtaGWmDHEdZcC71ryjTZVb1NB8Fpd5AwBOC5cWAwD6L2+roqo2aqM3VZOGx7hOM+BN8m7VdZ53tXVvresoAIAA12mRNcY8Y4zZZ4xZ327sv40xhcaYtcaYl40xg33jqcaYemPMat/XE+32mWaMWWeM2WqMWWiMMb7xMGPMS77xlcaY1J7/mACAAamlQf+IulKFsWcrIpQZQNciRk9VgqnRju1bXEcBAAS4U5mRfVbSRceMvSMp01qbLWmzpB+227bNWpvr+7qt3fjjkm6VNM73dfiYt0iqstaOlfSopJ93+VMAANABGxKpH9ddrZbRc1xHgaS4MTMkSQeL8h0nAQAEuk6LrLX2fUmVx4z901rb4vv2Y0kpJzuGMSZJUoy1doW11kp6XtLlvs1fkPSc7/UiSfMPz9YCAHA69hdvUd3BamUmc1mxP/AkZapVHgXvXes6CgAgwPXEPbJfk/RWu+/TjDGrjDHLjDHn+MaSJZW0e0+Jb+zwtmJJ8pXjaknxPZALADDABb92u14I/ZmykmNdR4EkhQ7S7shJqj54SG2/1wYAoHtOq8gaY+6R1CLpRd9QmaRR1topkr4n6Q/GmBhJHc2wHv4JdrJtx57vVmNMnjEmr7y8/HSiAwD6O69XkZUbtMGmalISM7L+4sO5f9JPG69RSVW96ygAgADW7SJrjLlJ0iWSrvddLixrbaO1tsL3Ol/SNknj1TYD2/7y4xRJpb7XJZJG+o4ZLClWx1zKfJi19klr7XRr7fTExMTuRgcADARVOxTWekj7Bk3UoDCeNucvJiVFS5I28DxZAMBp6FaRNcZcJOkuSZdZa+vajScaY4J8r9PVtqjTdmttmaRaY8xs3/2vN0p6xbfbq5Ju8r2+WtJiy/VGAIDTVbam7c/hOW5z4CiTQsv1Wuh/6FDBO66jAAAC2Kk8fuePklZImmCMKTHG3CLpMUnRkt455jE7cyStNcasUdvCTbdZaw/Prn5T0lOStqptpvbwfbVPS4o3xmxV2+XId/fMRwMADGSHduaryQZpSFq26yhoJ3zwMGV5iuQp/cx1FABAAOv0Witr7XUdDD99gvf+VdJfT7AtT1JmB+MNkr7YWQ4AALpiQ/zFeqHZ6vqR3IriV8JjtS8kWYOrC1wnAQAEsJ5YtRgAAL/z8aFhetV7liaPYKEnf1MzeLLGtGxVdX2z6ygAgABFkQUA9D+HKhS66VVlx1tFh4e4ToNjmBE5GuUp1+aiYtdRAAABiiILAOh/dq3Qbfse0Lz4A66ToANxE+fq9dbZ2r57j+soAIAARZEFAPQ7dTvz1WqNYtNyXUdBBwZPPEf3h31feVWDXEcBAAQoHqwHAOh36netUrFN1qRRw11HQQeMMZqUFKPtpXtdRwEABCiKLACg3wnfv07r7USdPyLWdRScwA/qf6WoylVqbt2gkCAuEAMAdA0/OQAA/UvtXg1q2q/SiPGKjWChJ38VkpCuVJVpB/fJAgC6gSILAOhfoobqmrDHVZJyqeskOImY9OnyGKuyTZ+6jgIACEAUWQBAv1JV16xPqmOVOmq06yg4iWHjZ0qSGnatcpwEABCIKLIAgH6lcsljusyzXFnJ3B/rz4IHj1CVGazwivWuowAAAhCLPQEA+pXEdU9qQdBoZYyIcR0FnViadIuWlIVojrUyxriOAwAIIMzIAgD6j7pKxTSWqThsvIYMCnWdBp2ozbpRr9Zna09Ng+soAIAAQ5EFAPQfZWskSc1DsxwHwamYNCxSk02Rtm7f7joKACDAUGQBAP1GffFnkqRBqVMdJ8GpmDTooN4M+w+1bHjVdRQAQIDhHlkAQL9RtadY5d5EjUtlxeJAEDU0TdWKVsi+da6jAAACDDOyAIB+4/URd2h+0/8ok4WeAoMxKo0Yr8SDha6TAAACDEUWANBvrN9do8TYKMVHhbmOglNUFz9Zqa07dbCuznUUAEAAocgCAPqHkjxdv/V7Oi+xxnUSdEFoyhSFmRbtKvzMdRQAQAChyAIA+oWGHSs0q/UzpSYPdx0FXZCQfYFuaLpbaw7FuY4CAAggFFkAQL9QuyNfe+1gjUkb4zoKumB4UorWhk3T2vJW11EAAAGEIgsA6BeC9q7Tem+aMpJZ6CmQGGN0aXypknYsch0FABBAKLIAgMDXVKfBh7arKGSMhkaHu06DLrrE85G+XvMbtba0uI4CAAgQFFkAQOCrr9TaoAzVJk51nQTd4BmRowjTpJKta11HAQAECIosACDgHQofrivqfig7doHrKOiG+LEzJEkVWz5xnAQAECgosgCAgFdQekDWSlnJsa6joBtGjs9Vgw1Ry+7VrqMAAAJEsOsAAACcrlF/v0I/DU5UZvJ811HQDaGhoSoMTtegqkLXUQAAAYIZWQBAYGtpUlz1RrWERGtYTJjrNOimP6X/l25pvdt1DABAgKDIAgACW3mBgtWiuvhMGWNcp0E3jRydrj0HW7WvtsF1FABAAKDIAgACWlPxKklS2MgpjpPgdGTGeXV/8LMqW/VP11EAAAGAIgsACGjV2/NUYyOUMmay6yg4DRNShurLQe/Ju/U911EAAAGAIgsACGiFIZP1dMvnlJkyxHUUnIbBMdHa4RmtiP3rXUcBAAQAiiwAIKC9Zs/S78Ov04jYcNdRcJr2DZqgpPpNkrWuowAA/BxFFgAQuBpqVFJcpMzkWBZ66geaErMUa2vVULHLdRQAgJ+jyAIAAlbTxtf1h+obNWdIheso6AGRqVNVauNUvHOb6ygAAD9HkQUABKzqbXmqt6FKHpPlOgp6wIiMc3Rm42PKax3rOgoAwM9RZAEAActbulob7WhlpsS5joIeMDJukKLCglVQVuM6CgDAz1FkAQCByetVbHWBtnjSlTIkwnUa9ACPx+jOmCX68vqvu44CAPBzFFkAQGCq2qFwb51qhmSw0FM/MiImRBObN8pbs8d1FACAH6PIAgACUlNYnP6t5VtqHj3HdRT0oNCRUyRJ5Vs+dZwEAODPKLIAgIC0udqjv7acrdHpE1xHQQ8aNn6GJKl6e57jJAAAf0aRBQAEpP2rXtMYs1tZybGuo6AHjR05Qju8w6WyNa6jAAD8GEUWABB4rNXMVT/UN8P+oVFxka7ToAeFhwTpo/A52tQ6wnUUAIAfC3YdAACALqsuVmRrjapjJ7PQUz/0Sfq39OmOSl3qOggAwG8xIwsACDgtu1dLkjwjchwnQW+YnBSjPdV1qjpQ7ToKAMBPUWQBAAGnauunarEeJYyd6joKekFmgkdrw/5F1ct+7ToKAMBPUWQBAAGnuWSVttpkZYwa5joKesH4USN0QFFqLV3tOgoAwE9xjywAIOA8N/yH+nhfgV6OH+Q6CnpBYnSYlnjGKKNqo+soAAA/xYwsACDgfLJXChuRIY+HhZ76q8qYSRraVCw11LiOAgDwQxRZAEBAaSnO19w9z2r6UEpsf+Ydni1Jai5d6zgJAMAfdVpkjTHPGGP2GWPWtxuLM8a8Y4zZ4vtzSLttPzTGbDXGbDLGXNhufJoxZp1v20Lje16CMSbMGPOSb3ylMSa1Zz8iAKA/ObD2TX3H/EWTkod0/mYErJgxs/TLliu1oynadRQAgB86lRnZZyVddMzY3ZLes9aOk/Se73sZYyZLulZShm+f3xhjgnz7PC7pVknjfF+Hj3mLpCpr7VhJj0r6eXc/DACg/2ssXqUddrgmpY5wHQW9aExqqn7ZcrXWHIxzHQUA4Ic6LbLW2vclVR4z/AVJz/lePyfp8nbjf7LWNlprd0jaKmmmMSZJUoy1doW11kp6/ph9Dh9rkaT5hqfbAwBOYFDlehWYdKUlRLmOgl6UljBICSENqt76sesoAAA/1N17ZIdZa8skyffnUN94sqTidu8r8Y0l+14fO37UPtbaFknVkuI7Oqkx5lZjTJ4xJq+8vLyb0QEAAetQhQY37VVl9EQFsdBTvxbkMfpB9Dv6auGtUnO96zgAAD/T04s9dfS/CnuS8ZPtc/ygtU9aa6dba6cnJiZ2MyIAIFC1VmxXgw2RHZ7jOgr6QFNiloLkld2zvvM3AwAGlO4W2b2+y4Xl+3Ofb7xE0sh270uRVOobT+lg/Kh9jDHBkmJ1/KXMAABoR/hEZTQ+o6gJc11HQR+ITJ0mSarenuc4CQDA33S3yL4q6Sbf65skvdJu/FrfSsRpalvU6RPf5ce1xpjZvvtfbzxmn8PHulrSYt99tAAAHGXd7mq1KkiZIzu8AwX9TGraeFXaKB0syncdBQDgZ4I7e4Mx5o+S5klKMMaUSPqRpIck/dkYc4ukXZK+KEnW2g3GmD9L2iipRdLt1tpW36G+qbYVkCMkveX7kqSnJf3eGLNVbTOx1/bIJwMA9DsT3r9DXwkdqzGJF7uOgj4wMSlGn9k0jd+3znUUAICf6bTIWmuvO8Gm+Sd4/4OSHuxgPE9SZgfjDfIVYQAATqihWpOrFmti9EgFB/X0Eg/wR4PCgvXHQTcoZXCU/sN1GACAX+F/AgCAgOAtXdv257Asx0nQl0zKDP2jimcGAwCORpEFAASEqm2fSpJi06c7ToK+lDk8QjkH3tXB7StdRwEA+JFOLy0GAMAf1O38TM12iMalj3EdBX1owojB+krI0zq0slpR6bNcxwEA+AlmZAEAAaGsOVLv2ykaNyzKdRT0ockjhmijHS2zZ43rKAAAP8KMLAAgIDwa9DXVDW3RNSz0NKAMiwnTe0FjNKXmXam1RQrivy4AAGZkAQABwHq9Wl9arYzkWNdR0MeMMaoZPFmhtlGq2OI6DgDAT1BkAQB+r3LZb/Sm93ZNS3SdBC54knMlSa2lXF4MAGhDkQUA+L1DRfmKNA2akDrSdRQ4MDQ9S2c2LNS24Z9zHQUA4CcosgAAvxdWvl4bbZrGDY92HQUOTBoxRKVK0MayWtdRAAB+giILAPBvLY2Kr9umPZHjFRYc5DoNHBiTGKU5wRuVtvwuyet1HQcA4AcosgAAv2b3blSwWtU0NNt1FDgSEuTRtNga5ex/Tara4ToOAMAPUGQBAH5tT71HL7TMV0TaLNdR4JB3WNsvMmwZCz4BACiyAAA/t7p+qO5tuUVjxk50HQUOxaXlqMkGqa4o33UUAIAfoMgCAPxaybZ1CvFYTWChpwFtYnK8Cu0oNe361HUUAIAfoMgCAPxXY61uWf0l3RfzhsJDWOhpIJuYFKNPvRPVWF8nWes6DgDAsWDXAQAAOJHWnSsVJK9aR0x3HQWOxUaE6HdRX1f+8MH6jTGu4wAAHGNGFgDgt8o3LlOrNRo6eY7rKPAD01Lj9GlRlSwzsgAw4FFkAQB+y1v0kTba0Zo+YaTrKPADM9PidGf9r3XoT7e4jgIAcIwiCwDwTy1NSqheq81hWRoaHe46DfzArLQ4BatVIdvflbxe13EAAA5RZAEAfqnVSv9qv6ddqVe5jgI/MSYxShtDMhTWXC3t3+w6DgDAIYosAMAvFZbX682GbKVOnuE6CvyEMUbekWe0fbPrI7dhAABOUWQBAH5p34o/Ktts08y0eNdR4EfSx2dqnx2sQ1s/dB0FAOAQRRYA4H+8Xs3Y8KBujVyq5MERrtPAj8xMT9ALLedra/A411EAAA7xHFkAgN+x5YWK8tbo4IiZrqPAz0wcHq1rQ67RXiUpx3UYAIAzzMgCAPzOvg3LJEnR489xnAT+xuMxmpkWp7U7SqWD5a7jAAAcocgCAPzOoS0faJ8drMxM5txwvFmpQ/SHg7eo7p2fuo4CAHCEIgsA8DuR+9dqbdBkjYof5DoK/NDM9ASt9aarZcdy11EAAI5QZAEAfsVaq6vsf2tJ2vdljHEdB34oY0SM1piJiqnZItVVuo4DAHCAIgsA8CtFFXXafdCryePHuo4CPxUc5FHtcN9CYMUr3YYBADhBkQUA+JXqd/9H/xq8SLN4fixOIn78GWqyQarnebIAMCBRZAEAfmXYjr9pZsh2jUnk/lic2PSxI/SD5m8of/BFrqMAABygyAIA/EddpZIad2h/3FTuj8VJZaXE6h+eOXqvMs51FACAAxRZAIDf2F/wviQpJO0sx0ng78KCgzQ7JULBm16T9m91HQf4/+3dd3xc1Z3//9eZGc2oV8vdxr2CCza2KaaGACmUDSyQUEJICIQENskmm3z5ZTeN7JJN2WSzIaGEQEJoAWISaigGDLjj3nC3XFWsLo00M+f3h8ZEsmxZGt3R0Ujv5+Ohh0b3zJ3P++jO6M5n5uqOiPQwNbIiItJrlG9YSJP1M3r6fNdRJAXMPSmbb9f8F42r/+w6ioiI9DA1siIi0mvsrWrmHTOTCcMGuo4iKWDGhFFstsOp++Bt11FERKSHqZEVEZFe4/sNV/Lo6Hvw+fT/sXJiM0cUsNJOJPvQSohGXMcREZEepEZWRER6hYNV9ewsr2feGJ28RzonI+jnUMEsQrF6OLjOdRwREelBamRFRKRXqHjpP3kt+HXmjcx2HUVSSGhsy4nBwruWOk4iIiI9SY2siIj0CoE9i4maNCYNH+A6iqSQqZOnMD/8c5YWXe46ioiI9CA1siIi4l40wrDatezJmU7Ar12TdN6skwrYZwazdOdh11FERKQH6dmCiIg4d3jHSjJpIDridNdRJMVkhwJcNLCK2Su/DRU7XMcREZEeokZWRESc27/mDQAGn3Ke4ySSiqYPz+Wcxtdo3vaW6ygiItJD1MiKiIhzSxuG8FDs40yaMMl1FElBYyfPosJmc3iTGlkRkf5CjayIiDj3RNloXh15B8GAdkvSdaeNLmJFbCLBvUtcRxERkR6iZwwiIuJUdfkhmg5uZO4ofX6sJCYvM42dWdPIb9wDNQddxxERkR6gRlZERJza895TvBb8BucU6qyz0g0nnck2O5Tmyr2uk4iISA9QIysiIk5Fdr7DYZvDxJNnuY4iKWzYyWdxQfgnrImNdh1FRER6gBpZERFxamDFSramn0x6MOA6iqSwOaNbDk1fur3ccRIREekJamRFRMSZuvIShsT2Uzd4jusokuIGZIe4JX8Z1719PjRWu44jIiJJlnAja4yZaIxZ1eqr2hjzL8aY7xpj9rZa/rFW63zbGLPVGLPZGHNRq+WzjDFr42O/NMaY7k5MRER6v50rXwMgf9I5jpNIXzBo6EhyYlVEdy91HUVERJIs4UbWWrvZWjvDWjsDmAXUA8/Gh39+ZMxa+wKAMWYKcA0wFbgY+LUxxh+//r3ALcD4+NfFieYSEZHU8ffwZG5r/hoTZpzhOor0AYOmnEXE+ijfsNB1FBERSTKvDi2+ANhmrd3VwXUuAx631oattTuArcAcY8wQINda+5611gKPAJd7lEtERHqxt/dEODDsI2RmZLiOIn3ArPEjWG9HEd35jusoIiKSZF41stcAj7X6+cvGmDXGmN8ZYwriy4YBe1pdpyS+bFj88tHL2zHG3GKMWW6MWV5aWupRdBERcaGh5jBz9v2BC4c2uY4ifcSQvAw2BU+mqGodRMKu44iI3M6HTAAAIABJREFUSBJ1u5E1xgSBS4Gn4ovuBcYCM4D9wE+PXPUYq9sOlrdfaO191trZ1trZxcXF3cotIiJubX//Df7N/yfOKKhyHUX6kPLhH+FRewmxpnrXUUREJIm8eEf2EmCltfYggLX2oLU2aq2NAfcDR05FWQKMaLXecGBffPnwYywXEZE+rGbL20Ssj7EzdaIn8U7xyefzvcar+aBaH+ckItKXedHIXkurw4rj//N6xBXAuvjl54BrjDEhY8xoWk7qtNRaux+oMcbMi5+t+AZggQe5RESkF8s9tIztgXHk5Bac+MoinTRvTBEhmti0VmcuFhHpy7rVyBpjMoELgWdaLf5x/KN01gDnAV8FsNauB54ENgAvAbdba6PxdW4DHqDlBFDbgBe7k0tERHq3cGM9Y8ObKB8wy3UU6WOGF2RwT+ajfOS9GyEWcx1HRESSpFvH3Vhr64Gio5Zd38H17wbuPsby5cDJ3ckiIiKpY8v695lIjPSxZ7mOIn2MMYbaQbPI2v937KENmMF6eiEi0hd5ddZiERGRTltYOZBp4QcYPe8y11GkD8qZcDaAPk9WRKQPUyMrIiI9bunOCkYNHkB+bo7rKNIHTZ0yjQO2gNoPFrmOIiIiSaJGVkREelRzJMItu7/BjQVrXUeRPmrswGzW+CaTV7oc7DE/0U9ERFKcGlkREelRW9ctZb5ZzZQi7YIkOYwxrBh+A9/2fdV1FBERSRI9ixARkR5VtuFNAIbPuMBxEunLhk4+nZeqR7HncIPrKCIikgRqZEVEpEellSymzBRSNGy86yjSh80ZXch83xpK3nncdRQREUkCNbIiItJjotEYo+vWsDd3JhjjOo70YRMH5XBL8GXGrPsf11FERCQJ1MiKiEiP2bTnIOtjI4mNOc91FOnjfD7DoYJTGRTeBXXlruOIiIjH1MiKiEiPeW9PA59r/iaDz/286yjSDwTHnAlA5ea3HCcRERGvqZEVEZEes3L7AUYWZjIkL8N1FOkHRk07i7BNo2yDGlkRkb4m4DqAiIj0D7GY5Ws7bqG04FRAhxZL8k0eXsxqxpJ7QJ9ZLCLS16iRFRGRHrFt1y7Gs4eGQZ9yHUX6iYDfx4PD72ZrtZ9XXIcRERFP6dBiERHpESVr3gBg4Mnnug0i/crUcaPYUlpPeW3YdRQREfGQGlkREekR0R3vEiaNgRNPdx1F+pF5o/P5UeB+Drz2a9dRRETEQ2pkRUQk6ay1DK58n5KMSZi0dNdxpB85ZXghp/q3kb71eddRRETEQ2pkRUQk6baX1fFI87nsn3Sj6yjSzwQDPnZnT2dozVqIRlzHERERj6iRFRGRpFuyvYIno+cx9IxrXUeRfigyfB4ZNFK7a4XrKCIi4hE1siIiknR7Ni5letZhRg/Ich1F+qFBJ7d83NO++AnHREQk9enjd0REJKmstZy/6xd8JliHMde5jiP90NRJk3gvNpWaw01McB1GREQ8oUZWRESSak9pNVNjm9k96ArXUaSfSk/z87OhP6Gp3vJR12FERMQTOrRYRESSasuad8g0YXInnOM6ivRjc0YXsm5vJXUNja6jiIiIB9TIiohIUtV/sAiAwaec6zaI9GtnDY6xOO1W9i580HUUERHxgBpZERFJqvyy5ZQGhuDLG+o6ivRjp0wcjw9o2v6O6ygiIuIBNbIiIpI0+6sa+Ne6G3h35o9dR5F+Ljs9jS2hkxlQoY/gERHpC9TIiohI0izZXsEhChg7Q/8fK+7VDj6NwdEDNFaUuI4iIiLdpEZWRESSpmzNK9yW/jKTB6a7jiJC3sSzAdj9/muOk4iISHepkRURkaQZsWcBt/oW4A8EXUcRYeL0M7k/8nGW1xS6jiIiIt2kRlZERJLiUE0jk5vWUV50KhjjOo4IedkZPFN8G38rLXYdRUREukmNrIiIJMWaDZsY6SslOPoM11FEPnT6qFwiu5fSVF/tOoqIiHSDGlkREUmKio0LARh8yvlug4i0clH2dp70f4ddK191HUVERLpBjayIiCRFzYHt1JksAkOnu44i8qFxM8+h2fqp3vKW6ygiItINamRFRMRzh+ua+EHlRTx85t/BH3AdR+RDRYWFbPWPJfvgMtdRRESkG9TIioiI55burADgtHFDHCcRaa+s6FRGN24iEq53HUVERBKkRlZERDxXuvolHg/ezbTsKtdRRNoJjjmToImwa+0i11FERCRBamRFRMRzod1vM9u3iVDuINdRRNoZNesSrm26i7dqh7uOIiIiCVIjKyIinqpubGZ0/RpKsydDMNN1HJF2Bg0sZl/Baby7W4cWi4ikKjWyIiLiqfe3HeAUs53YiHmuo4gc16VDKpm9/V5ikYjrKCIikgA1siIi4qnd6xYRMhEGTD3XdRSR45qfc4Av8md2bVruOoqIiCRAjayIiHhqw/4aVgdnEhp9husoIsc1fPr5ABxct9BtEBERSYgaWRER8UxdOMJTh4bz8qm/gawi13FEjmvIyPEcpIhAyWLXUUREJAFqZEVExDMrd5WTEatj7hg1sdK7GZ+PktwZjKxdjY3FXMcREZEuUiMrIiKe2bF+KatCX2BO0xLXUUROKDbidNJtA7v27HIdRUREukiNrIiIeKZ5+7v4jSVj+DTXUUROqHD+55gRvp/3DvpdRxERkS5SIysiIp5obI4ypGolVcFBkD/SdRyRExozqJDC7AyWbC93HUVERLoo4DqAiIj0Dat2H2aW2UTD4LPIcx1GpBOMMXy9YBFDt7yDta9gjHEdSUREOknvyIqIiCc2blzLIFNJ3qSzXUcR6bQJ+THOiS1l3949rqOIiEgXqJEVERFPLC5p4t6ML5Ix+SLXUUQ6bcDUcwHYtep1t0FERKRL1MiKiEi3NUVivLk3xsHJN0LBKNdxRDptxJQzCJNGZMc7rqOIiEgXqJEVEZFuW7u3kvnRpZwzJOI6ikiX+ILp7EyfzMDDK11HERGRLuhWI2uM2WmMWWuMWWWMWR5fVmiM+bsx5oP494JW1/+2MWarMWazMeaiVstnxW9nqzHml0ZnWxARSSlrNm/l/uDPmFPzd9dRRLqsYsRHWd88mAOVDa6jiIhIJ3nxjux51toZ1trZ8Z+/BbxmrR0PvBb/GWPMFOAaYCpwMfBrY8yRD267F7gFGB//utiDXCIi0kNqtrwNQNa4+Y6TiHRd9jl38PXmL7FkZ4XrKCIi0knJOLT4MuDh+OWHgctbLX/cWhu21u4AtgJzjDFDgFxr7XvWWgs80modERHp5SLRGPmly2k2QRg603UckS6bMjSX7JCf97eWuI4iIiKd1N3PkbXAK8YYC/zWWnsfMMhaux/AWrvfGDMwft1hwOJW65bElzXHLx+9vB1jzC20vHPLyJEjuxldRES8sGF/NTPsRqqKpjMgEHQdR6TL/D7Doxk/IboxDLztOo6IiHRCd9+RPdNaeypwCXC7MaajDw881v+92g6Wt19o7X3W2tnW2tnFxcVdTysiIp5bsaWEKWYXGWPPch1FJGGmaCyTIpspq6p1HUVERDqhW42stXZf/Psh4FlgDnAwfrgw8e+H4lcvAUa0Wn04sC++fPgxlouISAp4Z08D12X9lqwzv+g6ikjCssbPJ9OE2bJqkesoIiLSCQk3ssaYLGNMzpHLwEeBdcBzwI3xq90ILIhffg64xhgTMsaMpuWkTkvjhyHXGGPmxc9WfEOrdUREpBeLxSxLd1Rw0phJkDvEdRyRhI2Yfj7wjxOXiYhI79ad/5EdBDwb/6ScAPAna+1LxphlwJPGmJuB3cBVANba9caYJ4ENQAS43Vobjd/WbcDvgQzgxfiXiIj0cpsO1HBD81OclX4GMM11HJGEBQuGcsA/hJxDy11HERGRTki4kbXWbgemH2N5OXDBcda5G7j7GMuXAycnmkVERNxYtu0AtwcWEInkuY4i0m2rxt7Gn9dXMbW+mbzMNNdxRESkA8n4+B0REeknDmxeSoZpIme8Pj9WUl/+vOt4NTqLZfo8WRGRXk+NrIiIJMRaS2hv/FPVRp7uNoyIB2YMz2OGfxc7NixzHUVERE5AjayIiCRkW2ktUyMbqMkcCTmDXMcR6bb0ND+/D93DuA8ecB1FREROQI2siIgkZPH2CrJogFFnuo4i4g1jOJR/KuMb11IbjrhOIyIiHVAjKyIiCVmyo4KvZvyA7Cv/z3UUEc/4R5/BcFPGug3rXUcREZEOqJEVEZEui0RjvLetnDmjizA+v+s4Ip4ZOq3l82RLNyx0G0RERDrUnc+RFRGRfmrh5lLubLyX8xuygEdcxxHxTMbw6TSYDNJKlriOIiIiHdA7siIi0mVPLN3JRwMrGZJpXUcR8ZY/wILpv+VfD1/BrvI612lEROQ41MiKiEiXHKhqJPLBqwyiAt/Uy1zHEfHcueddRIMviz8t3e06ioiIHIcaWRER6ZKnlu/h075XiWYWw+RLXccR8dzgvHR+OPRdhiz9T8KRqOs4IiJyDGpkRUSk02Ixy8KlK7jA/z7+WTdCIOg6kkhSnF1YxbWx53lj5UbXUURE5BjUyIqISKct2lrGtirYMvl2mPVZ13FEkmbIBV8iZCKUv/2g6ygiInIMamRFRKTTHl+2G5NZyOhPfR/yR7iOI5I0vkGT2Zc/i/lVf2XrgUrXcURE5ChqZEVEpFNKa8JUb3idu0ZtIaS9h/QDOWfdykhfKUtefcp1FBEROYqeioiISKc8vbKEr/j/zGVlvwWM6zgiSZcz43KW51zAi1sbaWjSSZ9ERHoTNbIiInJC1lqWLF7EXN8m0ubcDD7tPqQfCASJXHE/ixrH8Lc1+1ynERGRVvRMRERETmjx9grOrfkrUV8QZl7vOo5Ij5k7upDTi+pZ//ZfXEcREZFW1MiKiMgJPbNkE58KLMJOuRyyilzHEekxxhj+K/NRvlz5Y9bvPuQ6joiIxKmRFRGRDlXWN7FxwzoaQwMIzPm86zgiPW7AubcxwFSz9tU/uo4iIiJxamRFRKRDz6zcy7rIcA7dsAhGzHEdR6THZU2+kLLgMMbteoLacMR1HBERQY2siIh0wFrLi4tXc9rwDKYMywejsxVLP+TzEZ5+I7PNJha+9YbrNCIighpZERHpwMrdh7mm6n4eqvsyxPTxI9J/DT3389STwQfvv4W11nUcEZF+T42siIgc14J31/JJ32JCky8Gn991HBFnTFYRf73wDX5RMY/391S6jiMi0u+pkRURkWOqbmwme+MTBE2EtHlfcB1HxLmPzx5PVtDPU+9udh1FRKTfC7gOICIivdOC90u4mr9TO3gu2QMnu44j4lx2KMCDxY+Tv3EFVXUryMsKuo4kItJv6R1ZERE5pnXvvshJvkNknXmL6ygivcbIKfOYZHbz9ht/cx1FRKRfUyMrIiLtrC2p4onSkbww9w+YyZe6jiPSawydfz11JpP0Vb/XSZ9ERBxSIysiIu08tmw36Wl+zjz3Egjo8EmRDwWz2DfqCuY3v8OKjR+4TiMi0m+pkRURkTbqwhEGvv8rfjfgMfJCOlOxyNFGXng7IRNh7+v3u44iItJvqZEVEZE2Xli1i8+YF5iSXQs+7SZEjhYaOpWnRv+A7+8/jbLasOs4IiL9kp6hiIhIGzsXPUGxqSZv/q2uo4j0WjMvuYnyaBZPLS9xHUVEpF9SIysiIh/adKCas6sWUJ0+DDPuI67jiPRa4wbmcOfgdeQt+j6xmE76JCLS09TIiojIh157803m+jYRmHOzDisWOYGPDargmuYFLF21ynUUEZF+R89SREQEgMbmKM9trOLN/CvInHuj6zgivd6oj34JawwVb/3WdRQRkX5HjayIiADw4rr9bG4sIO0TP4GsAa7jiPR6oaKT2FZwFnMPP8/+8krXcURE+hU1siIiAsDat57jk/k7mDe60HUUkZSRP/9Wikw1q175g+soIiL9ihpZERFh68Eariz/Df/hfxifz7iOI5IyBs64hGUZZ/HKtgYi0ZjrOCIi/YYaWRERYdHCF5ji20Xo9C+AUSMr0mk+HxWfeJBna6fy+qZDrtOIiPQbamRFRPq5cCTKgE1/pMFkknPap13HEUk5F0wayNicCCvefM51FBGRfkONrIhIP7fw/U1cGHuXinH/BKFs13FEUk7A7+MXBU/xlYPfoeSA3pUVEekJamRFRPq5pUvfpd5kMviC211HEUlZg8+/lWzTyIaXH3AdRUSkX1AjKyLSj+0ur+fBPUP54xmv4B88xXUckZQ1YOKZ7A6OY9SOx2lqjrqOIyLS56mRFRHpx/7y7loCJsaVc0e5jiKS2oyhfvqNTGAXyxa95DqNiEifp0ZWRKSfao7GmLHy//FS7o8YkpfhOo5Iyht/wU3UkMnelS+7jiIi0uepkRUR6afeXbmKM2Mr8I0523UUkT7Bn57Dk2c8xzdLL2LroVrXcURE+jQ1siIi/VT12/eDMYz8yG2uo4j0GZeePo2Az/DE4u2uo4iI9GlqZEVE+qF95VWcXvU3dhScSaBolOs4In1GcU6Inw15lU+vvJrGpmbXcURE+iw1siIi/dDKvz/GAFNN3vxbXUcR6XMmTpnOaPax/NU/u44iItJnJdzIGmNGGGPeMMZsNMasN8bcGV/+XWPMXmPMqvjXx1qt821jzFZjzGZjzEWtls8yxqyNj/3SGGO6Ny0RETmeaMxyz/Yx/GTADyme8bETryAiXTLhnGuoMPmEVv3OdRQRkT6rO+/IRoCvW2snA/OA240xRz6E8OfW2hnxrxcA4mPXAFOBi4FfG2P88evfC9wCjI9/XdyNXCIi0oG3tpSyp7qZyWdfCT4dmCPiNRMIseukK5kVXsYHmze4jiMi0icl/AzGWrvfWrsyfrkG2AgM62CVy4DHrbVha+0OYCswxxgzBMi11r5nrbXAI8DlieYSEZGO1bz8Q76Z8RwXThnkOopInzXm4tuxwN7Xf+06iohIn+TJS/HGmFHATGBJfNGXjTFrjDG/M8YUxJcNA/a0Wq0kvmxY/PLRy0VExGOlZeWcV/EkZxdWEgzo3ViRZMkbPIYnhn2Lu/fPoTYccR1HRKTP6fazGGNMNvA08C/W2mpaDhMeC8wA9gM/PXLVY6xuO1h+rFq3GGOWG2OWl5aWdje6iEi/s/7lB8gxDRScq4/cEUm2iRd9kQ+ainhu1T7XUURE+pxuNbLGmDRamthHrbXPAFhrD1pro9baGHA/MCd+9RJgRKvVhwP74suHH2N5O9ba+6y1s621s4uLi7sTXUSk34lFYwzb+id2BsYw7ORzXMcR6fNOHZnPPxftJO2N79Hy31MiIuKV7py12AAPAhuttT9rtXxIq6tdAayLX34OuMYYEzLGjKblpE5LrbX7gRpjzLz4bd4ALEg0l4iIHNu6pa8y3u6kcur1oJPDiySdMYarh5dyVeOf2bxmqes4IiJ9SnfekT0TuB44/6iP2vlx/KN01gDnAV8FsNauB54ENgAvAbdba6Px27oNeICWE0BtA17sRi4RETmGv22q5nnmM+mjN7uOItJvTLzoVsI2jYo3ddInEREvBRJd0Vq7iGP/f+sLHaxzN3D3MZYvB05ONIuIiHSsvDbM77dm8em59/DxrDzXcUT6jezCwawsOJ9p5S9TVXWYvLyCE68kIiInpFNWioj0A4tffZYRsT1cO2ek6ygi/U7u2beRbRpY/9IDrqOIiPQZamRFRPo4G4syc/V/8Mvsh5k4OMd1HJF+Z9zMc1kcnMeiHTU66ZOIiEfUyIqI9HFb3n2OofYA1afc6DqKSP9kDLsvfIBfV85l2c7DrtOIiPQJamRFRPq45sX3UWbzmH7hda6jiPRbn5g+hIJ0eGfhcU8lIiIiXaBGVkSkD6vev53JNe+xbtClZGZkuo4j0m9lBgP8auDz3L7zTioO7XUdR0Qk5amRFRHpw1Ysfp1Gggw5/zbXUUT6vWHn3UzQRNjy0m9cRxERSXlqZEVE+ihrLffsmsANRY8ycdJU13FE+r1Rk2exPu0URu54glg06jqOiEhKUyMrItJHrdlewqYDNVwxZ4LrKCISVz/jswy1B9nw9rOuo4iIpDQ1siIifVTO05/h3uD/ctmMoa6jiEjctI98hjLyKV+5wHUUEZGUpkZWRKQPqi9Zy5j61cSGzCAnPc11HBGJC4UyeGL67/lc2TUcrG50HUdEJGWpkRUR6YNKXvkVYZvG8Au+4DqKiBzl4/PnEI3BE0t3uY4iIpKy1MiKiPQ14VqG71nA28GzmDZ+jOs0InKUUQOyuGvIMi5753Ii4QbXcUREUpIaWRGRPmbfokfItA00zvgsxhjXcUTkGGZMmcJJdh8b3/iT6ygiIilJjayISB/zQOVp3Bm9k7POvcR1FBE5jhnn/RN7GEzo/d+Bta7jiIikHDWyIiJ9hbUc3Ludp9ZUYKZeQX5WyHUiETmOtECAraM/zYTwOtY9dpfrOCIiKUeNrIhIH1Hz4nfJuH8+QzjEreeOdR1HRE7g9Gv/H29lfpSxm+/nhbeXuo4jIpJS1MiKiPQB1S//iJyl/8Mrdi7/9bmPMWlwrutIInIC6cE05tz5KN8b/L/c/kIpz6wscR1JRCRlqJEVEUlxVa/+hNz37mGBPYcxn7ufU08qch1JRDopPRTkP26+itPHFLH86Z+x6pmfuo4kIpIS1MiKiKSw8uVPk7foB7xgz2DkTb9TEyuSgjKCfh68YTafyl7PjDXf5/0Fv3QdSUSk11MjKyKSovZWNnD1a9n81F7HkJseZuaoAa4jiUiCMkIBJt/5NKuDpzJ95b+z8m/3uY4kItKrqZEVEUlB5Sue5Qu/fYWDDXDB5+9m5qiBriOJSDdlZmYz7o4FbAhNY9qyf2PFiw+5jiQi0mupkRURSTHl7/2Rgr/exHUNf+IPN89lxoh815FExCNZ2bmM/spzfBCczCvvLOPFtftdRxIR6ZXUyIqIpJDypU+S9/JXWM4UTr7xf9TEivRBWTn5jPjqaywfdh1feex9Xlm903UkEZFeR42siEiKKFvxF/JeuJW1jCfjhqeYNnqI60gikiTZmRn8/qbTuGzQIWY8cw4r3njWdSQRkV5FjayISArYU1ZNzd/uYiOjSLvhz5wyZpjrSCKSZDnpaXz3+oupD+QxeeEXWfHW31xHEhHpNdTIioj0cnsq6rn2weXcYu/Cd/2znDxmpOtIItJDcgoHU3jbi1QEipn42s2sWPSy60giIr2CGlkRkV7s4Lo3WPp/N1HbEOZnn/84U8ee5DqSiPSw3AHDyL3lRar9BYz/+2dZuuw915FERJxTIysi0ksd3LCI7D9fy6zoav503WROGZ7nOpKIOJI7aCRZt7zAwvQLuGlBGW9uKXUdSUTEKTWyIiK90IFNi8l88ioqyKXx0wuYMm6U60gi4lje4DGcfefvOKk4n3975HWWL1/sOpKIiDNqZEVEepkDW1aQ/viV1JBJ/TXPMmnCRNeRRKSXyM8M8ujn53Jv+v8x8q9Xs2LlMteRREScUCMrItKL7C6v5+6n3qaSbGqvfoaJk6a6jiQivUxBVpAx1/+KoC/G0AX/zIpV77uOJCLS49TIioj0EnsOlHHNfe/xdnQKtTe/w4TJ011HEpFeKu+kaXD9X8jyNTHo2atYuXat60giIj1KjayISC+wd8dmAr+Zx4VNf+ePN8/l5BFFriOJSC+XP2YWsc88Q4Gpo/rPd7Bke7nrSCIiPUaNrIiIYyW7PoCHP0km9dxwxaWcPExnJxaRzskfN5emzzzLr7Lv4KbfL2PZzgrXkUREeoQaWRERh0p2byf2+0+SSzVllz/O2GlnuI4kIimmYPw8fv3FSxiam8bKh77Gqs3bXEcSEUk6NbIiIo7sPlBK00OXMsBWUHbpnxg742zXkUQkRQ3MTeeJy3O5yfyNtD99itUf7HQdSUQkqdTIiog4sLOsjqsfWsMznM+hT/yB0aee7zqSiKS4onGnUXv575lg9sAfr2T11t2uI4mIJI0aWRGRHrZ77z6+85vHaGyO8rEv/JBRsy9yHUlE+ojCGZ+g5tIHmGq2E/nDVazdvs91JBGRpFAjKyLSg3buO0jVA5fxy8j3ePzGk5kyNNd1JBHpYwpPvYLqj93LBLOHHzyygDUlla4jiYh4To2siEgP2bm/lMP3X85ku5W6j/6EiScNdR1JRPqowjlXU3PrSvZlTOS6B5awruSw60giIp5SIysikmSHahp59rVFHLrvCqbZTRz8yP8y/IyrXccSkT5u6ODBPPaFeXwu8BJlD3yK+597g22lta5jiYh4IuA6gIhIX1RaE+adpYt55oMYi3bVc6tvAZemrefgeT9l2FnXuY4nIv3EiMJMbjxrPHkLH+LclZezevkYfp99DlkzP8W58+ZQnBNyHVFEJCHGWus6Q0Jmz55tly9f7jqGiMiHymrDvLv4XRpXP8O0qjeY5NvD99O/Qfasf+bScSHGFhhM/kjXMUWkP6rYQe2qZ6hf9TQDq9fzl+gZfD36FeaPH8CnJ8BZp51KZlDvb4hI72KMWWGtnX3MMTWyIiKJK68N89L6A7z1/ia+tu9rTPSVALA3ZzqBU65g4LxrMLlDHKcUEWnl8C52HqrkqZ0hVq1YwqNNd7DRjmLHwI9QPPdqTj31NPw+4zqliIgaWRERL5XXNLJ4ySLCq59hz+EGfh65kjFFmfxfxr0UTjyTgXOuxOQNcx1TROSEYrVl7Fn4O9iwgJPq1wHwASN5feqPOPOMs5k6NBdj1NSKiBtqZEVEuqmironFi9+madVTnFL9JmPNPqL42FZ4DtGrHmHS4Bw92RORlNZYvpsdbz2Gb/PzXFNzB4ejGdyav4zzB9Uzcv61DB4303VEEeln1MiKiCTgcG2YJe8t5E+7cnhneyV3+R7mxsArlOTNInjKFQyeeyUmZ5DrmCIinqusb+L5tfspevMuPlr3N3zGUhIYSeWoj3HS2Z8hZ+Q01xERiV3sAAAW60lEQVRFpB9QIysi0kmHa8Mse+91mtY8wynVCznJHOKO9LsZPuMjXDbWMGFIISa72HVMEZEeU7J7B1vffIy8nc8zLbKepXYKj0z4Xy6fOYxzi2sJFY8FHZEiIkmgRlZEpAOH65p4ZcMBlq9czh37vskIU0oEP7vzTiM07Z8Yevo/YzILXMcUEXHKWsvGD7byxqrNPLQlhK0tZWn6lzgcHEbzxE8y+PSrMUNmqKkVEc+kRCNrjLkY+AXgBx6w1v5XR9dXIysiHbHWUt3QTEVFKRVVNRyI5lFWG6Z4x1/w1ezDV19OWriCjObDvNY0lfsjH2N0QZB7M+4l++RLGDbvU5jMQtfTEBHplSLRGO9u3Mm+RX9kxP5XmMt6AiZGZWgoq+b+DDtsFoMadzLowBuEcovJyBuIP2cgZBZB3ggIBF1PQURSQK9vZI0xfmALcCFQAiwDrrXWbjjeOmpkRfofay1VZfupKi2hpuIAjVWlNFcf4nBzgIWZH6Wstolr99/DmKbN5MSqKaCGNBNlUXQq1zXfBcDC0FcZZQ7SSIgafz6NafkcKphJ8OM/5uRhOjuniEhX1YYjLFy5kQNLn2Zk2Vv8NHIVm+1I/sn3Fj8L/qbd9b+S8z+U5UzmwsibXFL9BI3BAiKhQmKZRZA5gIqpN5GdP4CiWBk51JOVPxBfVhH49Tm3Iv1NR41sb/mLMAfYaq3dDmCMeRy4DDhuI9ubNUdjbN29h2DN3nZj4fwx2EAG/sbDpNXuO8b4WGwgHX9DGWl1B9uPF4zH+oME6g8RqC9tN95YOAl8fgJ1Bwg0lLcfL5oCxhCo3Ueg8XCbMWt8hIsmA5BWU4I/XNV23BcgXDixZbx6F/6m2rbj/jTCBRMACFbtxNdc12Y8FkinKX9sy3jlNnyRxrbjaZk05Y1uGT/8Ab5oU5vxaDCb5tyTAAhVbMbEIm3HQ7k054xoGS/fiLGxtuPp+TRnt3wkSnrZ+na/m0hGEZGswRCLkl6xqf145gAimYMg1kx6xZZ2481Zg4hmDMBEw4QOb20/nj2EaHohJtJAqHLbMcaHE03Px9dcR7BqR7vxptyRxIK5+JqqCVbvajcezhlNLJiNv7GStJpdfNiOxV+sCheMJxrIIlBfSrBmN2Cx2A/HGwac3HLfrD1AqGb3h8stLd/rB87E+kOkVe8mrXoXNhohFm3GRiPYWJRDQ8+n2frJLl9DVuUmbDQCsUj8e5T1o24gGrMMPbiQoqp1EGtZTixC1PhZOPLLRGKW6QeeYWjNWoyN4G+uJ9R0mLpYgC/6/oPy2iYe8t/NfP+6NnPfaofyvdBMBmSHMGkZ1AdPoia9gH2ZA/BnD6BgwHhemjyfAdkhCmJvQXou6cFM0uPrj2j32xQRkc7KDgX4xOmnwOmnUNXQzK9rw1TWN1PdcBp/rfk84aqDNNeUE6srxdSXQdoomhtjbKvxsyVcSHZDFQW2hIGmmjxTz6z3p1BOHl8N/Jk7A898WKeabGr8efzH4F+TkZ3HGbWvMKFuJTHjB58fawLEfEFeO+lOfD7D5Io3GNSwFWv8GF8A6wsQTctk0/Cr8fkMwyveIzd8AOsL4PO3jMfScigbcjY+YyisWkewuRbj87W8yGkMsUAGtUXTwUDO4Q0EIvUYAwYfGIilZVNfOAmfMWRVbMAfDYMBgwEfRNNyaS4YhzGGjIqN+GLNLfvr+IuosfS8fzzXKd+AsdE2v+toqIDmnOEApJe13RcCRNKLiGQPARsjvbz90+hIxoD4c50I6RWb2403Zw4kmll8/OcyWYOJZhRhIo3HeS4zrNVzmZ3txptyhhML5eFrqiFYvbv9eO5JxILZ+MJVBGtK2o2H80Zj0zI78Ty6nLS6A+3HT/g8eiL4Ap14Hr2fQGNFmzFrDOGiKcDxnkf7CRdOahmv3o2/qabt+AmfR4doyh/XMl65HV+koe146+fRlVvxRcJtxqPBLJpzRwH/eB7dlDuCCSOHp+znRveWRnYYsKfVzyXAXEdZuu1wfRO/vv8+/jf4q3Zjl4Z/wBo7lmv8r/NfaQ+0G78g/N9ss8O42f8C30n7Y7vxuY2/4iCF3OF/hq+l/bnd+CmND1BDJt8OPMoXA8+3Gx/d+EcsPu4OPMhnAq+1Gau3IaaEHwLgf9J+xeX+d9uMl9o8TgvfC8D9aT/lQv+KNuM7YoP4eNPPAfhT2g85w9/2D+j62El8vOk/AVgQ/P+Y7tveZnxJbBJXN/07AK8Fv85Y3/42469HZ/C55m8CsDh0O4NN20b8r9F5fKX5DgDWhG4m17R9gD8WOY9vR74AwPbQZ/CZtkcjPBi5hB9ErieDRjamf46j/SJyBT+PXEUxlSxL/1K78R81X8t90U8yyuxnYejr7cbvav4cj0Y/wlSzg+dDd7Ubv7PpSyyIncUcs5EnQz9oN/75pq/zamwW5/ne56Hgf7cbv7bpLt6LTeWTvne7ed97nu+kPdpu/Mh9707/03w17el241c3PkBtB/e9f1o1I37fe44LA6/RZP1E8RPBTx3p/GbHx/D7DP/uX8M0VhAzfppMiDp/PjWhwZw9qpgBOSFqw7ezLNBARt4gcgoHkTdgCGMKBrIk7chhavPb1W5r8AnGRUQkUXkZaeRlpLVaMhAY3+Y6n/7w0hnAvwLQ2BylqqGZAzX13Bu2VDY0Ey3N4bWyuVBXhq+hHH9jBcGmSsrCAaqrqpjZsJUh0ZX4ieIjip8oMevjcweuIBqz/KfvRU73vdWmdrnN4fo1LWdc/m3ag5zub3t03+5YMZ9p+gUAf0y7m9P8bV/43hgbwVVN9wDwbPDfmeFr2+wtj03g003fBeCV4DeY4Gv7psab0Wnc2PwtAN4JfYVhpm2z9Hx0Drc3/wsAq0JfIN+0bWaeipzNNyK3AvBB6HrSTNtG96HIRXwvciMhmtic/lmO9qvIZfwkcjUFVPN++q3txu9pvoZ7o5cy3BxiUehf2o3/e/ONPBK9iElmNy+FvtVu/OtNt/J07Gxmmc08Hfpeu/EvNv0LL8fmcI5vNQ8H72k3fl3Tt1kUO4VLfEu4N/iLduNXhL/H+3Y8V/kX8t9p97Ub/2j4HrbYEXzW/xLfTXuk3fiZjb9gL8Xc7v8L30h7st349Mb7qCKbfws8xm2Bv7YbH9f4CBECfC/wEDcG/t5mLGzTmBh+GICfpt3Lp/xvtxmvsNmcGm7J/Ju0n3Oxf1mb8T2xYj4Sv+/9Ie1H7V603xgbwcdb3fdmHuO+d2X8vvdy8JuM97V9IaD1fW9R6A6GmzJuavoG//fdb5EZ7C0tYdf0lkOLrwIustZ+Pv7z9cAca+1XjrreLcAtACNHjpy1a1f7d6V6g8bmKItXrSXvcPtXyiqKTyMSzCO9roTcyvbv+pUPnEc0LZvM2l1kV33Qbrxs8FnE/OlkVW8jq6b9u3alQ87B+tLIrtpCZm37V7oODb0AjCGnciMZdW3/uFrjo3To+QDkVqwlvaHtO8IxXxplQ84BIK98FaHGsjbj0UAG5YPOBCC/bDnBcGWb8UhaNhUD5wFQcGgJac1tX4lqCuZTWdxy5EDhwXcJROrbjIfTi6gqavkMuwEH3mr3jm1jxkCqC1t2TsX73mj3KmZD5lBqClpeKRu499V2v5v67BHU5k3ExCIU71/YbrwuZzR1uWPxRcMMOPB2u/Ha3HHU54zCH6mj6OB77cZr8ifSkDWCQFM1BaVL248XTKUxcwhp4Qryy1a2G68qnEZTxkCCjWXkVaxuN15ZNJNIqJBQw0FyDsdfRDDmw1d6K4tOJRLMJb1+P1nVR/74mfiLwIbKATOJBTIJ1e0jq3bnh+u38FE1oOUd2fTaEtIbD+Dzp2F8/pbv/gDNhRMIBAKkNVWSFmvE5w/gD6Th8/lbvody8Pt9BIzB5zcEfD78PoPfZ/AZdEiviIgkhY1FiUaaiUabiUWiRIPZRKOWWH0FsXAdsVgzsUjLUUZRawjnjyUWs/jLN2EaK7HRGNbGsEA0kEn9gGlYIOPQanxNNYDF2pavSDCX2qLpWCzZB5fja64HYkcOcqIpmE910TSsteTvfwdftOnDo6MslnB68YfPZQbsfxNj2x591pgx5MPnMsX7Xvvw6KkjGrKGU5s/CWyU4n1vtPtd1OeMoi53HCbaRPGBt9qN1+aOpT5nNP5IPUUH3203XpM3kYbsEQSaayg8tKTdeHXBFBozh5IWPkxB2Yp241WFpxDOGESwsYz88lXtxiuLZtKUXkSo4SB5FWvbjR8unk1zMJ/0ur3kVm5sN37keXRG7W5yqtofPVc26ExigQwya7aTXb293XjpkLOxviBZVR+QVdu+zzg09HwwPnIqN5FR17ZRtMZQOvQCAHIPryO9vu07wm2fR68m1Nj2HeGoP53ywWcBkF+2gmC47Rs2kbQsKgaeDkBB6VLSmqrbjDcH8zhcfBoAhQffIxBp+yJIU6iQygGnAlB04G380TCVRdOZP2MqAb+v3Vx7i1T4H9nTge9aay+K//xtAGvtfx5vHf2PrIiIiIiISN/VUSPbW9rvZcB4Y8xoY0wQuAZ4znEmERERERER6YV6xQHR1tqIMebLwMu0fPzO76y17c/GIyIiIiIiIv1er2hkAay1LwAvuM4hIiIiIiIivVtvObRYREREREREpFPUyIqIiIiIiEhKUSMrIiIiIiIiKUWNrIiIiIiIiKQUNbIiIiIiIiKSUtTIioiIiIiISEpRIysiIiIiIiIpRY2siIiIiIiIpBQ1siIiIiIiIpJS1MiKiIiIiIhISlEjKyIiIiIiIilFjayIiIiIiIikFDWyIiIiIiIiklLUyIqIiIiIiEhKUSMrIiIiIiIiKUWNrIiIiIiIiKQUNbIiIiIiIiKSUoy11nWGhBhjSoFdrnOcwACgTHX6fZ2erKU6qtPTtVSnd9fpyVqqozo9XUt1enednqylOr27TnecZK0tPtZAyjayqcAYs9xaO1t1+nednqylOqrT07VUp3fX6claqqM6PV1LdXp3nZ6spTq9u06y6NBiERERERERSSlqZEVERERERCSlqJFNrvtUR3V6uJbqqE5P11Kd3l2nJ2upjur0dC3V6d11erKW6vTuOkmh/5EVERERERGRlKJ3ZEVERERERCS1WGv11cEXcDGwGdgKfCu+rBD4O/BB/HtBq+t/O37dzcBFrZbPAtbGx37JP94NDwFPxJdvArYlsdbZwEogCuz1oM7dwB6g9qjf2ZE57QMagJ1JqtPl+QBFwBtALfCro27vRNuo0/NJsI7X8znR9unSfS7BWh3N6SpgPRADZh+1XqKPo2NtIy/reD2fRB5DXtY5Mp8I8EPa/607Zq0T3Bc820YJ1unyNjpBHc+2UYJ1jswnBlQB61qNJWNfVA00A5uTVMfr+Zxo+3g1H8+2zwnuB515rnCIlo/LSFYtr+fk2TZKsE5H80nGfuhY80nGfigCvB6/P3R3Tolso2Tsizq9jU5wX/BsGyVYx+v5eLZ9EqzT+j53Zesx11/OA/TmL8BPy5P8MUAQWA1MAX7MP56wfAu4J355Svw6IWB0fF1/fGwpcDpggBeBS+LLvwT8Jl7rIPC3JNYaBcwAauJ1u1tnHjDkGHf4LwG/jV/3DuCpJNVJZD5ZwFnArbR/AHe0jbo6n0TqeD2fjrZPIve5RGp1NKfJwERgIW3/yCb6ODreNvKyjtfzSeQx5GWdUcA04A/AAdr/rTteLa8fR17WSWQbJfo48nI+J9pGLwHfoO0TomTsi86O31ZVkup4PZ8T/Z3zaj5ebp9EHz+/iV/+LvByEmt5PScvt5HXjyGv90PHm4/X+6FpwCPAd4BTPZhTItsoGfuirmyjhB9HXZyP148hr/dDXs7nRNvnEXpZI6tDizs2B9hqrd1urW0CHgcui389HL/Ow8Dl8cuXAY9ba8PW2h20vEIzxxgzBMi11r5nW+4Rjxy1zsPxWqtpuRM1J6OWtXYnkEHLKzeHujOn+O0tttbuP8bv7TJgefy6vwbOS0adROZjra2z1i4CGlvfVie2UZfmk0gdL+fT0e+NBO9zidTqaE7W2o3W2s3HyZfI4+iY28jLOl7Op6Pfm5fz6aiOtXantXYNLe9+HDj6b93xann9OPKyTiLbqBuPI0/m01GdVtvoAC2voB+dwdN9kbX2LVqa8ixjjPG6jpfz6ej35uV8OqqTyHy68fg5cls/BE5LVi0v5xQf82wbef0YSsJ+6Jjz8Xo/FJ9PDNgIVHRnTh397rycU0d1EtlG3XkcdWU+Xj+GkrAf8mQ+HdU56j7Xq6iR7dgwWt5iP6IkvmzQkQ0d/z7wBNcfFr989PLW6wwDdtNyCEJRkmodWa/Ogzl1ZBgtr07tsdZG4nOqTEKdRObT0e10tI26Op9E6ng5nxNlSOQ+1516x5rTifIdff1Et5GXdbycT0e8nE9nZNJyqGIi6x6dwcttlEidI+Nd2UaJ8HI+iUrGvghaDsuO0vJ3wes6Xs6nI17OJ1Fe74f2xG8rQssRB/4k1epIMvZF0Plt1FO8fgx5WSdRXj+OvKzjJa+3USJ1eoqX80lJamQ7Zo6xzCZw/Y5uxxz1vfWY17U6Wq+rdTpieqhOd9bryu0kMp9E6nRm3AuJ3ue6W6+1ZDyOeqJOR+t1tU5HevIxdDx6HJ04Q0/USUR39kXHGvOyTiK8zOb1Ol7q6vZJVq2e0hsyHE9fewx1VKs3rOMlr7dRInV6Sm/I4JQa2Y6VACNa/TyclhN7HIwfUnDk0IJDJ7h+Sfzy0ctbr1MCjATyaDlMJBm1jqyX5cGcOlJCy+EHI4wxgfic8pNQJ5H5dHQ7HW2jrs4nkTpezudEGRK5z3Wn3rHmdKJ8R18/0W3kZR0v59MRL+fTGfXAgATXPTqDl9sokTpHxruyjRLh5XwSlYx9EbS80+fnH4cser0f8mo+HfFyPonyej80In5bASCHlndfklGrI8nYF0Hnt1FP8fox5GWdRHn9OPKyjpe83kaJ1OkpXs4nJamR7dgyYLwxZrQxJghcAzwX/7oxfp0bgQXxy88B1xhjQsaY0cB4YGn8sJgaY8y8+LHrNxy1zo3xWtOBJUBakmodmVMuMLA7czrB7+05YHb8urfR8o/myaiTyHyOqRPbqKvzSaSOZ/M5gUTvc4k63pw6ypfI4+h428jLOp7Np4PrezqfE9Q5ogwYcoy/dV2ShG2USB3o+jZKhGfz6WYGr/dFAB8D6uL/9+V1Hc/m04Xb6tZ8OpG7q/M5pi5snyuBd5NYqyPJ2BdB57dRT/H6MeRlHU/n1Il1PJlTN3J3SRK2USJ1eopn80lZtheccao3f9Fyx9hCy1nX7oovKwJeo+W08K8Bha2uf1f8upuJn70svnw2sC4+9iv+cYrudFr+QfvIacp3JLHWabS8etNIyyu5Td2s82P+8a5ECfDdo+Z05GMpdiWpTqLz2UnLK1a18fWndHIbdXU+Xa3j9XxOtH0Suc91tVZHc7oiPham5ezJL3vwODrWNvKyjtfzSeQx5GWdI/Opo+XkSOGj7gsd1TrefcHrbdTVOoluo+PV8XobdbXOkflE4mM2/vPNJGdfVBP/nTUnqY7X8znR9vFqPl5vn+PdDzrzXKGclncoOzunrtbyek5eb6Ou1uloPsnYDx1rPsnYD9XFb6/Zg1qJbKNk7Iu6uo2Od1/weht1tY7X8/F6+3S1Tuv7XDmw/shtuf468gsXERERERERSQk6tFhERERERERSihpZERERERERSSlqZEVERERERCSlqJEVERERERGRlKJGVkRERERERFKKGlkRERERERFJKWpkRUREREREJKWokRUREREREZGU8v8DJgIGwn6Nck8AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 1152x648 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def pad(x, numQubits):\n",
    "    \"\"\"\n",
    "    Utility function that returns a left padded version of the bit string\n",
    "    passed.\n",
    "    \"\"\"\n",
    "    string = str(x)[2:]\n",
    "    string = ('0' * (numQubits - len(string))) + string\n",
    "    return string\n",
    "\n",
    "regBounds = [i for i in range(-16, 17)]\n",
    "qc, a, c = encodeDist(distribution, regBounds)\n",
    "numQubits = (qc.num_qubits + 2) // 2\n",
    "\n",
    "for i in range(numQubits - 2, 2 * numQubits - 2):\n",
    "    qc.measure(a[i], c[i - (numQubits - 2)])\n",
    "\n",
    "backend = Aer.get_backend('qasm_simulator')\n",
    "shots = 100000\n",
    "job = execute(qc, backend=backend, shots=shots)\n",
    "results = job.result().get_counts()\n",
    "resultsX = []\n",
    "resultsY = []\n",
    "\n",
    "for i in [pad(bin(x), numQubits) for x in range(2 ** (numQubits))]:\n",
    "    resultsX.append(i)\n",
    "    if i in results.keys():\n",
    "        resultsY.append(results[i])\n",
    "    else:\n",
    "        resultsY.append(0)\n",
    "\n",
    "truthDisc = [integrate(distribution, regBounds[i], regBounds[i + 1]) * shots for i in range(\n",
    "    len(regBounds) - 1)]\n",
    "\n",
    "plt.figure(figsize=[16, 9])\n",
    "plt.plot(resultsX, resultsY)\n",
    "plt.plot(resultsX, truthDisc, '--')\n",
    "plt.legend(['quantum estimate', 'classical estimate'])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's take a look at the quantum circuit:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "circuit_drawer(qc, output='latex')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Things to do next\n",
    "Looks like we're done - awesome!\n",
    "\n",
    "Taking all the functions from this notebook and pasting them into a python file will give you a working copy of this program, provided you have all the dependencies installed - if you want a regular python file instead, you can get a copy [here](https://github.com/SashwatAnagolum/DoNew/blob/master/loadProbDist/loadProbDist.py).\n",
    "\n",
    "A possible next step after getting the hang of encoding distributions is to figure out ways to process the quantum state further, leading to purely quantum transformed versions of the distribution.\n",
    "\n",
    "Let me know if you figure out any other ways we can work with the quantum state we get using this circuit, or if you have any other questions - you can reach me at [sashwat.anagolum@gmail.com](mailto:sashwat.anagolum@gmail.com)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
